83#include "llvm/ADT/APFloat.h"
84#include "llvm/ADT/APInt.h"
85#include "llvm/ADT/APSInt.h"
86#include "llvm/ADT/ArrayRef.h"
87#include "llvm/ADT/DenseMap.h"
88#include "llvm/ADT/FoldingSet.h"
89#include "llvm/ADT/STLExtras.h"
90#include "llvm/ADT/STLForwardCompat.h"
91#include "llvm/ADT/SmallBitVector.h"
92#include "llvm/ADT/SmallPtrSet.h"
93#include "llvm/ADT/SmallString.h"
94#include "llvm/ADT/SmallVector.h"
95#include "llvm/ADT/StringExtras.h"
96#include "llvm/ADT/StringRef.h"
97#include "llvm/ADT/StringSet.h"
98#include "llvm/ADT/StringSwitch.h"
99#include "llvm/Support/AtomicOrdering.h"
100#include "llvm/Support/Compiler.h"
101#include "llvm/Support/ConvertUTF.h"
102#include "llvm/Support/ErrorHandling.h"
103#include "llvm/Support/Format.h"
104#include "llvm/Support/Locale.h"
105#include "llvm/Support/MathExtras.h"
106#include "llvm/Support/SaveAndRestore.h"
107#include "llvm/Support/raw_ostream.h"
108#include "llvm/TargetParser/RISCVTargetParser.h"
109#include "llvm/TargetParser/Triple.h"
122using namespace clang;
126 unsigned ByteNo)
const {
137 unsigned ArgCount =
Call->getNumArgs();
138 if (ArgCount >= MinArgCount)
141 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
142 << 0 << MinArgCount << ArgCount
143 << 0 <<
Call->getSourceRange();
147 unsigned ArgCount =
Call->getNumArgs();
148 if (ArgCount <= MaxArgCount)
150 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
151 << 0 << MaxArgCount << ArgCount
152 << 0 <<
Call->getSourceRange();
156 unsigned MaxArgCount) {
162 unsigned ArgCount =
Call->getNumArgs();
163 if (ArgCount == DesiredArgCount)
168 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
172 Call->getArg(ArgCount - 1)->getEndLoc());
174 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
175 << 0 << DesiredArgCount << ArgCount
180 bool HasError =
false;
182 for (
const Expr *Arg :
Call->arguments()) {
183 if (Arg->isValueDependent())
186 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
187 int DiagMsgKind = -1;
189 if (!ArgString.has_value())
191 else if (ArgString->find(
'$') != std::string::npos)
194 if (DiagMsgKind >= 0) {
195 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
196 << DiagMsgKind << Arg->getSourceRange();
205 if (
Value->isTypeDependent())
236 if (!Literal || !Literal->isOrdinary()) {
249 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
257 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
258 if (!Literal || !Literal->isWide()) {
259 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
260 << Arg->getSourceRange();
297 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
328 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
330 auto IsValidIntegerType = [](
QualType Ty) {
331 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
338 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
340 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
343 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_type);
345 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_member_pointer);
347 S.
Diag(Source->getExprLoc(),
348 diag::note_alignment_invalid_function_pointer);
353 if (!IsValidIntegerType(AlignOp->
getType())) {
364 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
365 llvm::APSInt MaxValue(
366 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
367 if (AlignValue < 1) {
368 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
371 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
376 if (!AlignValue.isPowerOf2()) {
377 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
380 if (AlignValue == 1) {
381 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
382 << IsBooleanAlignBuiltin;
410 std::pair<unsigned, const char *> Builtins[] = {
411 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
412 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
413 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
416 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
423 auto ValidCkdIntType = [](
QualType QT) {
426 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
427 return (BT->getKind() >= BuiltinType::Short &&
428 BT->getKind() <= BuiltinType::Int128) || (
429 BT->getKind() >= BuiltinType::UShort &&
430 BT->getKind() <= BuiltinType::UInt128) ||
431 BT->getKind() == BuiltinType::UChar ||
432 BT->getKind() == BuiltinType::SChar;
437 for (
unsigned I = 0; I < 2; ++I) {
443 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
462 !PtrTy->getPointeeType()->isIntegerType() ||
463 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
464 PtrTy->getPointeeType().isConstQualified()) {
466 diag::err_overflow_builtin_must_be_ptr_int)
474 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
475 for (
unsigned I = 0; I < 3; ++I) {
476 const auto Arg = TheCall->
getArg(I);
479 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
481 return S.
Diag(Arg->getBeginLoc(),
482 diag::err_overflow_builtin_bit_int_max_size)
491struct BuiltinDumpStructGenerator {
495 SmallVector<Expr *, 32> Actions;
496 DiagnosticErrorTrap ErrorTracker;
497 PrintingPolicy Policy;
499 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
500 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
501 Policy(S.Context.getPrintingPolicy()) {
503 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
506 Expr *makeOpaqueValueExpr(Expr *Inner) {
510 Actions.push_back(OVE);
514 Expr *getStringLiteral(llvm::StringRef Str) {
517 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
520 bool callPrintFunction(llvm::StringRef Format,
521 llvm::ArrayRef<Expr *> Exprs = {}) {
522 SmallVector<Expr *, 8> Args;
524 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
526 Args.push_back(getStringLiteral(Format));
527 llvm::append_range(Args, Exprs);
530 Sema::CodeSynthesisContext Ctx;
543 Actions.push_back(RealCall.
get());
549 Expr *getIndentString(
unsigned Depth) {
553 llvm::SmallString<32>
Indent;
555 return getStringLiteral(
Indent);
562 bool appendFormatSpecifier(QualType T, llvm::SmallVectorImpl<char> &Str) {
563 llvm::raw_svector_ostream
OS(Str);
567 if (
auto *BT = T->
getAs<BuiltinType>()) {
568 switch (BT->getKind()) {
569 case BuiltinType::Bool:
572 case BuiltinType::Char_U:
573 case BuiltinType::UChar:
576 case BuiltinType::Char_S:
577 case BuiltinType::SChar:
585 analyze_printf::PrintfSpecifier
Specifier;
588 if (
Specifier.getConversionSpecifier().getKind() ==
589 analyze_printf::PrintfConversionSpecifier::sArg) {
595 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
615 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
616 Expr *IndentLit = getIndentString(Depth);
618 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
619 : callPrintFunction(
"%s", {TypeLit}))
622 return dumpRecordValue(RD, E, IndentLit, Depth);
626 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
635 Expr *RecordArg = makeOpaqueValueExpr(E);
638 if (callPrintFunction(
" {\n"))
642 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
643 for (
const auto &Base : CXXRD->bases()) {
651 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
657 Expr *FieldIndentArg = getIndentString(Depth + 1);
660 for (
auto *D : RD->
decls()) {
661 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
662 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
663 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
666 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
667 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
669 getStringLiteral(FD->getName())};
671 if (FD->isBitField()) {
675 FD->getBitWidthValue());
683 CXXScopeSpec(), Loc, IFD,
686 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
688 DeclarationNameInfo(FD->getDeclName(), Loc));
689 if (
Field.isInvalid())
692 auto *InnerRD = FD->getType()->getAsRecordDecl();
693 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
694 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
696 if (callPrintFunction(Format, Args) ||
697 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
701 if (appendFormatSpecifier(FD->getType(), Format)) {
703 Args.push_back(
Field.get());
713 Args.push_back(FieldAddr.
get());
716 if (callPrintFunction(Format, Args))
721 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
722 : callPrintFunction(
"}\n");
725 Expr *buildWrapper() {
728 TheCall->
setType(Wrapper->getType());
749 diag::err_expected_struct_pointer_argument)
758 diag::err_incomplete_type))
767 switch (BT ? BT->getKind() : BuiltinType::Void) {
768 case BuiltinType::Dependent:
769 case BuiltinType::Overload:
770 case BuiltinType::BoundMember:
771 case BuiltinType::PseudoObject:
772 case BuiltinType::UnknownAny:
773 case BuiltinType::BuiltinFn:
779 diag::err_expected_callable_argument)
785 BuiltinDumpStructGenerator Generator(S, TheCall);
791 Expr *PtrArg = PtrArgResult.
get();
795 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
798 return Generator.buildWrapper();
810 if (
Call->getStmtClass() != Stmt::CallExprClass) {
811 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
812 <<
Call->getSourceRange();
817 if (CE->getCallee()->getType()->isBlockPointerType()) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
819 <<
Call->getSourceRange();
823 const Decl *TargetDecl = CE->getCalleeDecl();
824 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
825 if (FD->getBuiltinID()) {
826 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
827 <<
Call->getSourceRange();
832 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
833 <<
Call->getSourceRange();
841 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
855 BuiltinCall->
setType(CE->getType());
859 BuiltinCall->
setArg(1, ChainResult.
get());
866class ScanfDiagnosticFormatHandler
870 using ComputeSizeFunction =
871 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
875 using DiagnoseFunction =
876 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
878 ComputeSizeFunction ComputeSizeArgument;
879 DiagnoseFunction Diagnose;
882 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
883 DiagnoseFunction Diagnose)
884 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
886 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
887 const char *StartSpecifier,
888 unsigned specifierLen)
override {
892 unsigned NulByte = 0;
904 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
906 analyze_format_string::OptionalAmount::HowSpecified::Constant)
911 std::optional<llvm::APSInt> DestSizeAPS =
916 unsigned DestSize = DestSizeAPS->getZExtValue();
918 if (DestSize < SourceSize)
925class EstimateSizeFormatHandler
930 bool IsKernelCompatible =
true;
933 EstimateSizeFormatHandler(StringRef Format)
934 :
Size(std::
min(Format.find(0), Format.size()) +
937 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
938 const char *,
unsigned SpecifierLen,
939 const TargetInfo &)
override {
941 const size_t FieldWidth = computeFieldWidth(FS);
942 const size_t Precision = computePrecision(FS);
949 Size += std::max(FieldWidth, (
size_t)1);
961 Size += std::max(FieldWidth, Precision);
977 Size += std::max(FieldWidth, 1 +
978 (Precision ? 1 + Precision
988 (Precision ? 1 + Precision : 0) +
998 (Precision ? 1 + Precision : 0) +
1013 IsKernelCompatible =
false;
1014 Size += std::max(FieldWidth, 2 + Precision);
1061 Size += (Precision ? 0 : 1);
1068 assert(SpecifierLen <= Size &&
"no underflow");
1069 Size -= SpecifierLen;
1073 size_t getSizeLowerBound()
const {
return Size; }
1074 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1077 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1078 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1079 size_t FieldWidth = 0;
1085 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1086 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1087 size_t Precision = 0;
1134 StringRef &FormatStrRef,
size_t &StrLen,
1136 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1137 Format && (Format->isOrdinary() || Format->isUTF8())) {
1138 FormatStrRef = Format->getString();
1140 Context.getAsConstantArrayType(Format->getType());
1141 assert(T &&
"String literal not of constant array type!");
1142 size_t TypeSize = T->getZExtSize();
1144 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1150void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1156 bool UseDABAttr =
false;
1157 const FunctionDecl *UseDecl = FD;
1159 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1161 UseDecl = DABAttr->getFunction();
1162 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1174 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1181 unsigned DABIndices = DABAttr->argIndices_size();
1182 unsigned NewIndex = Index < DABIndices
1183 ? DABAttr->argIndices_begin()[Index]
1186 return std::nullopt;
1190 auto ComputeExplicitObjectSizeArgument =
1191 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1192 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1194 return std::nullopt;
1195 unsigned NewIndex = *IndexOptional;
1197 Expr *SizeArg = TheCall->
getArg(NewIndex);
1199 return std::nullopt;
1205 auto ComputeSizeArgument =
1206 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1212 if (Index < FD->getNumParams()) {
1213 if (
const auto *POS =
1215 BOSType = POS->getType();
1218 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1220 return std::nullopt;
1221 unsigned NewIndex = *IndexOptional;
1224 return std::nullopt;
1226 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1227 if (std::optional<uint64_t> ObjSize =
1230 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1232 return std::nullopt;
1235 auto ComputeStrLenArgument =
1236 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1237 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1239 return std::nullopt;
1240 unsigned NewIndex = *IndexOptional;
1242 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1244 if (std::optional<uint64_t>
Result =
1247 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1249 return std::nullopt;
1252 std::optional<llvm::APSInt> SourceSize;
1253 std::optional<llvm::APSInt> DestinationSize;
1254 unsigned DiagID = 0;
1255 bool IsChkVariant =
false;
1257 auto GetFunctionName = [&]() {
1258 std::string FunctionNameStr =
1260 llvm::StringRef FunctionName = FunctionNameStr;
1265 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1266 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1268 FunctionName.consume_front(
"__builtin_");
1270 return FunctionName.str();
1273 switch (BuiltinID) {
1276 case Builtin::BI__builtin_strcat:
1277 case Builtin::BIstrcat:
1278 case Builtin::BI__builtin_stpcpy:
1279 case Builtin::BIstpcpy:
1280 case Builtin::BI__builtin_strcpy:
1281 case Builtin::BIstrcpy: {
1282 DiagID = diag::warn_fortify_strlen_overflow;
1283 SourceSize = ComputeStrLenArgument(1);
1284 DestinationSize = ComputeSizeArgument(0);
1288 case Builtin::BI__builtin___strcat_chk:
1289 case Builtin::BI__builtin___stpcpy_chk:
1290 case Builtin::BI__builtin___strcpy_chk: {
1291 DiagID = diag::warn_fortify_strlen_overflow;
1292 SourceSize = ComputeStrLenArgument(1);
1293 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1294 IsChkVariant =
true;
1298 case Builtin::BIscanf:
1299 case Builtin::BIfscanf:
1300 case Builtin::BIsscanf: {
1301 unsigned FormatIndex = 1;
1302 unsigned DataIndex = 2;
1303 if (BuiltinID == Builtin::BIscanf) {
1308 const auto *FormatExpr =
1311 StringRef FormatStrRef;
1316 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1317 unsigned SourceSize) {
1318 DiagID = diag::warn_fortify_scanf_overflow;
1319 unsigned Index = ArgIndex + DataIndex;
1320 std::string FunctionName = GetFunctionName();
1322 PDiag(DiagID) << FunctionName << (Index + 1)
1323 << DestSize << SourceSize);
1326 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1327 return ComputeSizeArgument(Index + DataIndex);
1329 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1330 const char *FormatBytes = FormatStrRef.data();
1341 case Builtin::BIsprintf:
1342 case Builtin::BI__builtin___sprintf_chk: {
1343 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1346 StringRef FormatStrRef;
1349 EstimateSizeFormatHandler H(FormatStrRef);
1350 const char *FormatBytes = FormatStrRef.data();
1352 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1353 Context.getTargetInfo(),
false)) {
1354 DiagID = H.isKernelCompatible()
1355 ? diag::warn_format_overflow
1356 : diag::warn_format_overflow_non_kprintf;
1357 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1358 .extOrTrunc(SizeTypeWidth);
1359 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1360 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1361 IsChkVariant =
true;
1363 DestinationSize = ComputeSizeArgument(0);
1370 case Builtin::BI__builtin___memcpy_chk:
1371 case Builtin::BI__builtin___memmove_chk:
1372 case Builtin::BI__builtin___memset_chk:
1373 case Builtin::BI__builtin___strlcat_chk:
1374 case Builtin::BI__builtin___strlcpy_chk:
1375 case Builtin::BI__builtin___strncat_chk:
1376 case Builtin::BI__builtin___strncpy_chk:
1377 case Builtin::BI__builtin___stpncpy_chk:
1378 case Builtin::BI__builtin___memccpy_chk:
1379 case Builtin::BI__builtin___mempcpy_chk: {
1380 DiagID = diag::warn_builtin_chk_overflow;
1381 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1383 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1384 IsChkVariant =
true;
1388 case Builtin::BI__builtin___snprintf_chk:
1389 case Builtin::BI__builtin___vsnprintf_chk: {
1390 DiagID = diag::warn_builtin_chk_overflow;
1391 SourceSize = ComputeExplicitObjectSizeArgument(1);
1392 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1393 IsChkVariant =
true;
1397 case Builtin::BIstrncat:
1398 case Builtin::BI__builtin_strncat:
1399 case Builtin::BIstrncpy:
1400 case Builtin::BI__builtin_strncpy:
1401 case Builtin::BIstpncpy:
1402 case Builtin::BI__builtin_stpncpy: {
1408 DiagID = diag::warn_fortify_source_size_mismatch;
1409 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1410 DestinationSize = ComputeSizeArgument(0);
1414 case Builtin::BIbzero:
1415 case Builtin::BI__builtin_bzero:
1416 case Builtin::BImemcpy:
1417 case Builtin::BI__builtin_memcpy:
1418 case Builtin::BImemmove:
1419 case Builtin::BI__builtin_memmove:
1420 case Builtin::BImemset:
1421 case Builtin::BI__builtin_memset:
1422 case Builtin::BImempcpy:
1423 case Builtin::BI__builtin_mempcpy: {
1424 DiagID = diag::warn_fortify_source_overflow;
1425 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1426 DestinationSize = ComputeSizeArgument(0);
1429 case Builtin::BIbcopy:
1430 case Builtin::BI__builtin_bcopy: {
1431 DiagID = diag::warn_fortify_source_overflow;
1432 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1433 DestinationSize = ComputeSizeArgument(1);
1436 case Builtin::BIsnprintf:
1437 case Builtin::BI__builtin_snprintf:
1438 case Builtin::BIvsnprintf:
1439 case Builtin::BI__builtin_vsnprintf: {
1440 DiagID = diag::warn_fortify_source_size_mismatch;
1441 SourceSize = ComputeExplicitObjectSizeArgument(1);
1443 StringRef FormatStrRef;
1447 EstimateSizeFormatHandler H(FormatStrRef);
1448 const char *FormatBytes = FormatStrRef.data();
1450 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1451 Context.getTargetInfo(),
false)) {
1452 llvm::APSInt FormatSize =
1453 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1454 .extOrTrunc(SizeTypeWidth);
1455 if (FormatSize > *SourceSize && *SourceSize != 0) {
1456 unsigned TruncationDiagID =
1457 H.isKernelCompatible() ? diag::warn_format_truncation
1458 : diag::warn_format_truncation_non_kprintf;
1459 SmallString<16> SpecifiedSizeStr;
1460 SmallString<16> FormatSizeStr;
1461 SourceSize->toString(SpecifiedSizeStr, 10);
1462 FormatSize.toString(FormatSizeStr, 10);
1464 PDiag(TruncationDiagID)
1465 << GetFunctionName() << SpecifiedSizeStr
1470 DestinationSize = ComputeSizeArgument(0);
1474 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1478 if (!SourceSize || !DestinationSize ||
1479 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1482 std::string FunctionName = GetFunctionName();
1484 SmallString<16> DestinationStr;
1485 SmallString<16> SourceStr;
1486 DestinationSize->toString(DestinationStr, 10);
1487 SourceSize->toString(SourceStr, 10);
1490 << FunctionName << DestinationStr << SourceStr);
1505 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1508 << DRE->getDecl()->getIdentifier();
1520 "__builtin_alloca has invalid address space");
1533 if (Arg->isTypeDependent() || Arg->isValueDependent())
1536 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1538 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1546enum PointerAuthOpKind {
1561 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1592 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1595 llvm::raw_svector_ostream Str(
Value);
1604 Result = KeyValue->getZExtValue();
1623 bool IsAddrDiscArg =
false;
1628 IsAddrDiscArg =
true;
1637 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1638 <<
Result->getExtValue();
1640 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1646 IntVal =
Result->getZExtValue();
1650static std::pair<const ValueDecl *, CharUnits>
1657 const auto *BaseDecl =
1662 return {BaseDecl,
Result.Val.getLValueOffset()};
1666 bool RequireConstant =
false) {
1674 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1675 return OpKind != PAO_BlendInteger;
1677 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1678 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1679 OpKind == PAO_SignGeneric;
1688 }
else if (AllowsInteger(OpKind) &&
1695 <<
unsigned(OpKind == PAO_Discriminator ? 1
1696 : OpKind == PAO_BlendPointer ? 2
1697 : OpKind == PAO_BlendInteger ? 3
1699 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1709 if (!RequireConstant) {
1711 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1714 ? diag::warn_ptrauth_sign_null_pointer
1715 : diag::warn_ptrauth_auth_null_pointer)
1725 if (OpKind == PAO_Sign) {
1743 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1748 assert(OpKind == PAO_Discriminator);
1754 if (
Call->getBuiltinCallee() ==
1755 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1770 assert(
Pointer->getType()->isPointerType());
1782 assert(
Integer->getType()->isIntegerType());
1788 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1801 Call->setType(
Call->getArgs()[0]->getType());
1832 PointerAuthOpKind OpKind,
1833 bool RequireConstant) {
1844 Call->setType(
Call->getArgs()[0]->getType());
1860 Call->setType(
Call->getArgs()[0]->getType());
1869 const Expr *AddendExpr =
Call->getArg(5);
1871 if (!AddendIsConstInt) {
1872 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
1886 Call->setType(
Call->getArgs()[0]->getType());
1895 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1898 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1899 if (!Literal || Literal->getCharByteWidth() != 1) {
1915 Call->setArg(0, FirstValue.
get());
1921 if (!FirstArgRecord) {
1922 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1923 << 0 << FirstArgType;
1928 diag::err_get_vtable_pointer_requires_complete_type)) {
1933 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1934 << 1 << FirstArgRecord;
1938 Call->setType(ReturnType);
1963 auto DiagSelect = [&]() -> std::optional<unsigned> {
1970 return std::optional<unsigned>{};
1985 diag::err_incomplete_type))
1989 "Unhandled non-object pointer case");
2017 if (PT->getPointeeType()->isFunctionType()) {
2019 diag::err_builtin_is_within_lifetime_invalid_arg)
2025 if (PT->getPointeeType()->isVariableArrayType()) {
2027 << 1 <<
"__builtin_is_within_lifetime";
2032 diag::err_builtin_is_within_lifetime_invalid_arg)
2046 diag::err_builtin_trivially_relocate_invalid_arg_type)
2053 diag::err_incomplete_type))
2057 T->isIncompleteArrayType()) {
2059 diag::err_builtin_trivially_relocate_invalid_arg_type)
2060 << (T.isConstQualified() ? 1 : 2);
2069 diag::err_builtin_trivially_relocate_invalid_arg_type)
2076 if (Size.isInvalid())
2080 if (Size.isInvalid())
2082 SizeExpr = Size.get();
2083 TheCall->
setArg(2, SizeExpr);
2093 llvm::Triple::ObjectFormatType CurObjFormat =
2095 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2108 llvm::Triple::ArchType CurArch =
2110 if (llvm::is_contained(SupportedArchs, CurArch))
2120bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2127 case llvm::Triple::arm:
2128 case llvm::Triple::armeb:
2129 case llvm::Triple::thumb:
2130 case llvm::Triple::thumbeb:
2132 case llvm::Triple::aarch64:
2133 case llvm::Triple::aarch64_32:
2134 case llvm::Triple::aarch64_be:
2136 case llvm::Triple::bpfeb:
2137 case llvm::Triple::bpfel:
2139 case llvm::Triple::dxil:
2141 case llvm::Triple::hexagon:
2143 case llvm::Triple::mips:
2144 case llvm::Triple::mipsel:
2145 case llvm::Triple::mips64:
2146 case llvm::Triple::mips64el:
2148 case llvm::Triple::spirv:
2149 case llvm::Triple::spirv32:
2150 case llvm::Triple::spirv64:
2151 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2154 case llvm::Triple::systemz:
2156 case llvm::Triple::x86:
2157 case llvm::Triple::x86_64:
2159 case llvm::Triple::ppc:
2160 case llvm::Triple::ppcle:
2161 case llvm::Triple::ppc64:
2162 case llvm::Triple::ppc64le:
2164 case llvm::Triple::amdgcn:
2166 case llvm::Triple::riscv32:
2167 case llvm::Triple::riscv64:
2168 case llvm::Triple::riscv32be:
2169 case llvm::Triple::riscv64be:
2171 case llvm::Triple::loongarch32:
2172 case llvm::Triple::loongarch64:
2175 case llvm::Triple::wasm32:
2176 case llvm::Triple::wasm64:
2178 case llvm::Triple::nvptx:
2179 case llvm::Triple::nvptx64:
2185 return T->isDependentType() ||
2186 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
2201 switch (ArgTyRestr) {
2204 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2205 << ArgOrdinal << 2 << 1 << 1
2212 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2213 << ArgOrdinal << 5 << 0
2219 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2220 << ArgOrdinal << 5 << 1
2226 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2240 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2241 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2242 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2243 "Expecting __builtin_cpu_...");
2245 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2247 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2248 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2249 (!IsCPUSupports && TInfo->supportsCpuIs()));
2251 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2258 ? diag::err_builtin_aix_os_unsupported
2259 : diag::err_builtin_target_unsupported)
2265 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2303 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2304 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2305 BT->getNumBits() != 1) {
2307 << ArgTy << BT->getNumBits();
2383 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2386 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2395 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2396 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2416 TheCall->
setArg(0, Arg0);
2433 TheCall->
setArg(1, Arg1);
2439 << 2 << 1 << 4 << 0 << Arg1Ty;
2453 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2455 << (OnlyUnsigned ? 3 : 1)
2463 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2466 return OnlyUnsigned ? T->isUnsignedIntegerType() : T->isIntegerType();
2471 return emitError(S, Loc, T);
2476 return emitError(S, Loc, T);
2482 return emitError(S, Loc, T);
2487 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2492 return emitError(S, Loc, T);
2497 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2503 llvm_unreachable(
"conversion functions are permitted");
2522 TheCall->
setArg(0, Arg0);
2536 TheCall->
setArg(1, Arg1);
2547 unsigned Pos,
bool AllowConst,
2551 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2556 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2557 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2558 << Pos <<
"scalar pointer";
2567 diag::err_typecheck_convert_incompatible)
2576 bool TypeDependent =
false;
2577 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2605 Builtin::BI__builtin_masked_load))
2619 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2642 Builtin::BI__builtin_masked_store))
2650 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2660 diag::err_vec_builtin_incompatible_vector)
2689 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2702 << MaskTy << IdxTy);
2711 diag::err_vec_masked_load_store_ptr)
2740 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2756 << MaskTy << IdxTy);
2762 << MaskTy << ValTy);
2768 diag::err_vec_builtin_incompatible_vector)
2782 if (Args.size() == 0) {
2784 diag::err_typecheck_call_too_few_args_at_least)
2790 QualType FuncT = Args[0]->getType();
2793 if (Args.size() < 2) {
2795 diag::err_typecheck_call_too_few_args_at_least)
2801 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2802 QualType ObjectT = Args[1]->getType();
2804 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2853 tok::periodstar, ObjectArg.
get(), Args[0]);
2857 if (MPT->isMemberDataPointer())
2860 auto *MemCall =
new (S.
Context)
2884 return TyA->getElementType();
2891Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2896 unsigned ICEArguments = 0;
2898 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2903 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2905 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2910 if (ArgNo < TheCall->getNumArgs() &&
2913 ICEArguments &= ~(1 << ArgNo);
2917 switch (BuiltinID) {
2918 case Builtin::BI__builtin_cpu_supports:
2919 case Builtin::BI__builtin_cpu_is:
2921 Context.getAuxTargetInfo(), BuiltinID))
2924 case Builtin::BI__builtin_cpu_init:
2925 if (!
Context.getTargetInfo().supportsCpuInit()) {
2931 case Builtin::BI__builtin___CFStringMakeConstantString:
2935 *
this, BuiltinID, TheCall,
2936 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2939 "Wrong # arguments to builtin CFStringMakeConstantString");
2940 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2943 case Builtin::BI__builtin_ms_va_start:
2944 case Builtin::BI__builtin_stdarg_start:
2945 case Builtin::BI__builtin_va_start:
2946 case Builtin::BI__builtin_c23_va_start:
2947 if (BuiltinVAStart(BuiltinID, TheCall))
2950 case Builtin::BI__va_start: {
2951 switch (
Context.getTargetInfo().getTriple().getArch()) {
2952 case llvm::Triple::aarch64:
2953 case llvm::Triple::arm:
2954 case llvm::Triple::thumb:
2955 if (BuiltinVAStartARMMicrosoft(TheCall))
2959 if (BuiltinVAStart(BuiltinID, TheCall))
2967 case Builtin::BI_interlockedbittestandset_acq:
2968 case Builtin::BI_interlockedbittestandset_rel:
2969 case Builtin::BI_interlockedbittestandset_nf:
2970 case Builtin::BI_interlockedbittestandreset_acq:
2971 case Builtin::BI_interlockedbittestandreset_rel:
2972 case Builtin::BI_interlockedbittestandreset_nf:
2975 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2980 case Builtin::BI_bittest64:
2981 case Builtin::BI_bittestandcomplement64:
2982 case Builtin::BI_bittestandreset64:
2983 case Builtin::BI_bittestandset64:
2984 case Builtin::BI_interlockedbittestandreset64:
2985 case Builtin::BI_interlockedbittestandset64:
2988 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2989 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2994 case Builtin::BI_interlockedbittestandreset64_acq:
2995 case Builtin::BI_interlockedbittestandreset64_rel:
2996 case Builtin::BI_interlockedbittestandreset64_nf:
2997 case Builtin::BI_interlockedbittestandset64_acq:
2998 case Builtin::BI_interlockedbittestandset64_rel:
2999 case Builtin::BI_interlockedbittestandset64_nf:
3004 case Builtin::BI__builtin_set_flt_rounds:
3007 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3008 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
3009 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3010 llvm::Triple::ppc64le}))
3014 case Builtin::BI__builtin_isgreater:
3015 case Builtin::BI__builtin_isgreaterequal:
3016 case Builtin::BI__builtin_isless:
3017 case Builtin::BI__builtin_islessequal:
3018 case Builtin::BI__builtin_islessgreater:
3019 case Builtin::BI__builtin_isunordered:
3020 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3023 case Builtin::BI__builtin_fpclassify:
3024 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3027 case Builtin::BI__builtin_isfpclass:
3028 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3031 case Builtin::BI__builtin_isfinite:
3032 case Builtin::BI__builtin_isinf:
3033 case Builtin::BI__builtin_isinf_sign:
3034 case Builtin::BI__builtin_isnan:
3035 case Builtin::BI__builtin_issignaling:
3036 case Builtin::BI__builtin_isnormal:
3037 case Builtin::BI__builtin_issubnormal:
3038 case Builtin::BI__builtin_iszero:
3039 case Builtin::BI__builtin_signbit:
3040 case Builtin::BI__builtin_signbitf:
3041 case Builtin::BI__builtin_signbitl:
3042 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3045 case Builtin::BI__builtin_shufflevector:
3049 case Builtin::BI__builtin_masked_load:
3050 case Builtin::BI__builtin_masked_expand_load:
3052 case Builtin::BI__builtin_masked_store:
3053 case Builtin::BI__builtin_masked_compress_store:
3055 case Builtin::BI__builtin_masked_gather:
3057 case Builtin::BI__builtin_masked_scatter:
3059 case Builtin::BI__builtin_invoke:
3061 case Builtin::BI__builtin_prefetch:
3062 if (BuiltinPrefetch(TheCall))
3065 case Builtin::BI__builtin_alloca_with_align:
3066 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3067 if (BuiltinAllocaWithAlign(TheCall))
3070 case Builtin::BI__builtin_alloca:
3071 case Builtin::BI__builtin_alloca_uninitialized:
3078 case Builtin::BI__builtin_infer_alloc_token:
3082 case Builtin::BI__arithmetic_fence:
3083 if (BuiltinArithmeticFence(TheCall))
3086 case Builtin::BI__assume:
3087 case Builtin::BI__builtin_assume:
3088 if (BuiltinAssume(TheCall))
3091 case Builtin::BI__builtin_assume_aligned:
3092 if (BuiltinAssumeAligned(TheCall))
3095 case Builtin::BI__builtin_dynamic_object_size:
3096 case Builtin::BI__builtin_object_size:
3100 case Builtin::BI__builtin_longjmp:
3101 if (BuiltinLongjmp(TheCall))
3104 case Builtin::BI__builtin_setjmp:
3105 if (BuiltinSetjmp(TheCall))
3108 case Builtin::BI__builtin_complex:
3109 if (BuiltinComplex(TheCall))
3112 case Builtin::BI__builtin_classify_type:
3113 case Builtin::BI__builtin_constant_p: {
3122 case Builtin::BI__builtin_launder:
3124 case Builtin::BI__builtin_is_within_lifetime:
3126 case Builtin::BI__builtin_trivially_relocate:
3129 case Builtin::BI__sync_fetch_and_add:
3130 case Builtin::BI__sync_fetch_and_add_1:
3131 case Builtin::BI__sync_fetch_and_add_2:
3132 case Builtin::BI__sync_fetch_and_add_4:
3133 case Builtin::BI__sync_fetch_and_add_8:
3134 case Builtin::BI__sync_fetch_and_add_16:
3135 case Builtin::BI__sync_fetch_and_sub:
3136 case Builtin::BI__sync_fetch_and_sub_1:
3137 case Builtin::BI__sync_fetch_and_sub_2:
3138 case Builtin::BI__sync_fetch_and_sub_4:
3139 case Builtin::BI__sync_fetch_and_sub_8:
3140 case Builtin::BI__sync_fetch_and_sub_16:
3141 case Builtin::BI__sync_fetch_and_or:
3142 case Builtin::BI__sync_fetch_and_or_1:
3143 case Builtin::BI__sync_fetch_and_or_2:
3144 case Builtin::BI__sync_fetch_and_or_4:
3145 case Builtin::BI__sync_fetch_and_or_8:
3146 case Builtin::BI__sync_fetch_and_or_16:
3147 case Builtin::BI__sync_fetch_and_and:
3148 case Builtin::BI__sync_fetch_and_and_1:
3149 case Builtin::BI__sync_fetch_and_and_2:
3150 case Builtin::BI__sync_fetch_and_and_4:
3151 case Builtin::BI__sync_fetch_and_and_8:
3152 case Builtin::BI__sync_fetch_and_and_16:
3153 case Builtin::BI__sync_fetch_and_xor:
3154 case Builtin::BI__sync_fetch_and_xor_1:
3155 case Builtin::BI__sync_fetch_and_xor_2:
3156 case Builtin::BI__sync_fetch_and_xor_4:
3157 case Builtin::BI__sync_fetch_and_xor_8:
3158 case Builtin::BI__sync_fetch_and_xor_16:
3159 case Builtin::BI__sync_fetch_and_nand:
3160 case Builtin::BI__sync_fetch_and_nand_1:
3161 case Builtin::BI__sync_fetch_and_nand_2:
3162 case Builtin::BI__sync_fetch_and_nand_4:
3163 case Builtin::BI__sync_fetch_and_nand_8:
3164 case Builtin::BI__sync_fetch_and_nand_16:
3165 case Builtin::BI__sync_add_and_fetch:
3166 case Builtin::BI__sync_add_and_fetch_1:
3167 case Builtin::BI__sync_add_and_fetch_2:
3168 case Builtin::BI__sync_add_and_fetch_4:
3169 case Builtin::BI__sync_add_and_fetch_8:
3170 case Builtin::BI__sync_add_and_fetch_16:
3171 case Builtin::BI__sync_sub_and_fetch:
3172 case Builtin::BI__sync_sub_and_fetch_1:
3173 case Builtin::BI__sync_sub_and_fetch_2:
3174 case Builtin::BI__sync_sub_and_fetch_4:
3175 case Builtin::BI__sync_sub_and_fetch_8:
3176 case Builtin::BI__sync_sub_and_fetch_16:
3177 case Builtin::BI__sync_and_and_fetch:
3178 case Builtin::BI__sync_and_and_fetch_1:
3179 case Builtin::BI__sync_and_and_fetch_2:
3180 case Builtin::BI__sync_and_and_fetch_4:
3181 case Builtin::BI__sync_and_and_fetch_8:
3182 case Builtin::BI__sync_and_and_fetch_16:
3183 case Builtin::BI__sync_or_and_fetch:
3184 case Builtin::BI__sync_or_and_fetch_1:
3185 case Builtin::BI__sync_or_and_fetch_2:
3186 case Builtin::BI__sync_or_and_fetch_4:
3187 case Builtin::BI__sync_or_and_fetch_8:
3188 case Builtin::BI__sync_or_and_fetch_16:
3189 case Builtin::BI__sync_xor_and_fetch:
3190 case Builtin::BI__sync_xor_and_fetch_1:
3191 case Builtin::BI__sync_xor_and_fetch_2:
3192 case Builtin::BI__sync_xor_and_fetch_4:
3193 case Builtin::BI__sync_xor_and_fetch_8:
3194 case Builtin::BI__sync_xor_and_fetch_16:
3195 case Builtin::BI__sync_nand_and_fetch:
3196 case Builtin::BI__sync_nand_and_fetch_1:
3197 case Builtin::BI__sync_nand_and_fetch_2:
3198 case Builtin::BI__sync_nand_and_fetch_4:
3199 case Builtin::BI__sync_nand_and_fetch_8:
3200 case Builtin::BI__sync_nand_and_fetch_16:
3201 case Builtin::BI__sync_val_compare_and_swap:
3202 case Builtin::BI__sync_val_compare_and_swap_1:
3203 case Builtin::BI__sync_val_compare_and_swap_2:
3204 case Builtin::BI__sync_val_compare_and_swap_4:
3205 case Builtin::BI__sync_val_compare_and_swap_8:
3206 case Builtin::BI__sync_val_compare_and_swap_16:
3207 case Builtin::BI__sync_bool_compare_and_swap:
3208 case Builtin::BI__sync_bool_compare_and_swap_1:
3209 case Builtin::BI__sync_bool_compare_and_swap_2:
3210 case Builtin::BI__sync_bool_compare_and_swap_4:
3211 case Builtin::BI__sync_bool_compare_and_swap_8:
3212 case Builtin::BI__sync_bool_compare_and_swap_16:
3213 case Builtin::BI__sync_lock_test_and_set:
3214 case Builtin::BI__sync_lock_test_and_set_1:
3215 case Builtin::BI__sync_lock_test_and_set_2:
3216 case Builtin::BI__sync_lock_test_and_set_4:
3217 case Builtin::BI__sync_lock_test_and_set_8:
3218 case Builtin::BI__sync_lock_test_and_set_16:
3219 case Builtin::BI__sync_lock_release:
3220 case Builtin::BI__sync_lock_release_1:
3221 case Builtin::BI__sync_lock_release_2:
3222 case Builtin::BI__sync_lock_release_4:
3223 case Builtin::BI__sync_lock_release_8:
3224 case Builtin::BI__sync_lock_release_16:
3225 case Builtin::BI__sync_swap:
3226 case Builtin::BI__sync_swap_1:
3227 case Builtin::BI__sync_swap_2:
3228 case Builtin::BI__sync_swap_4:
3229 case Builtin::BI__sync_swap_8:
3230 case Builtin::BI__sync_swap_16:
3231 return BuiltinAtomicOverloaded(TheCallResult);
3232 case Builtin::BI__sync_synchronize:
3236 case Builtin::BI__builtin_nontemporal_load:
3237 case Builtin::BI__builtin_nontemporal_store:
3238 return BuiltinNontemporalOverloaded(TheCallResult);
3239 case Builtin::BI__builtin_memcpy_inline: {
3240 clang::Expr *SizeOp = TheCall->
getArg(2);
3252 case Builtin::BI__builtin_memset_inline: {
3253 clang::Expr *SizeOp = TheCall->
getArg(2);
3263#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3264 case Builtin::BI##ID: \
3265 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3266#include "clang/Basic/Builtins.inc"
3267 case Builtin::BI__annotation: {
3268 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3269 if (!TT.isOSWindows() && !TT.isUEFI()) {
3278 case Builtin::BI__builtin_annotation:
3282 case Builtin::BI__builtin_addressof:
3286 case Builtin::BI__builtin_function_start:
3290 case Builtin::BI__builtin_is_aligned:
3291 case Builtin::BI__builtin_align_up:
3292 case Builtin::BI__builtin_align_down:
3296 case Builtin::BI__builtin_add_overflow:
3297 case Builtin::BI__builtin_sub_overflow:
3298 case Builtin::BI__builtin_mul_overflow:
3302 case Builtin::BI__builtin_operator_new:
3303 case Builtin::BI__builtin_operator_delete: {
3304 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3306 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3309 case Builtin::BI__builtin_dump_struct:
3311 case Builtin::BI__builtin_expect_with_probability: {
3316 const Expr *ProbArg = TheCall->
getArg(2);
3317 SmallVector<PartialDiagnosticAt, 8> Notes;
3318 Expr::EvalResult Eval;
3322 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3329 bool LoseInfo =
false;
3330 Probability.convert(llvm::APFloat::IEEEdouble(),
3331 llvm::RoundingMode::Dynamic, &LoseInfo);
3332 if (!(Probability >= llvm::APFloat(0.0) &&
3333 Probability <= llvm::APFloat(1.0))) {
3340 case Builtin::BI__builtin_preserve_access_index:
3344 case Builtin::BI__builtin_call_with_static_chain:
3348 case Builtin::BI__exception_code:
3349 case Builtin::BI_exception_code:
3351 diag::err_seh___except_block))
3354 case Builtin::BI__exception_info:
3355 case Builtin::BI_exception_info:
3357 diag::err_seh___except_filter))
3360 case Builtin::BI__GetExceptionInfo:
3372 case Builtin::BIaddressof:
3373 case Builtin::BI__addressof:
3374 case Builtin::BIforward:
3375 case Builtin::BIforward_like:
3376 case Builtin::BImove:
3377 case Builtin::BImove_if_noexcept:
3378 case Builtin::BIas_const: {
3386 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3387 BuiltinID == Builtin::BI__addressof;
3389 (ReturnsPointer ?
Result->isAnyPointerType()
3390 :
Result->isReferenceType()) &&
3393 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3399 case Builtin::BI__builtin_ptrauth_strip:
3401 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3403 case Builtin::BI__builtin_ptrauth_sign_constant:
3406 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3409 case Builtin::BI__builtin_ptrauth_auth:
3412 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3414 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3416 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3418 case Builtin::BI__builtin_ptrauth_string_discriminator:
3421 case Builtin::BI__builtin_get_vtable_pointer:
3425 case Builtin::BIread_pipe:
3426 case Builtin::BIwrite_pipe:
3429 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3432 case Builtin::BIreserve_read_pipe:
3433 case Builtin::BIreserve_write_pipe:
3434 case Builtin::BIwork_group_reserve_read_pipe:
3435 case Builtin::BIwork_group_reserve_write_pipe:
3436 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3439 case Builtin::BIsub_group_reserve_read_pipe:
3440 case Builtin::BIsub_group_reserve_write_pipe:
3441 if (
OpenCL().checkSubgroupExt(TheCall) ||
3442 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3445 case Builtin::BIcommit_read_pipe:
3446 case Builtin::BIcommit_write_pipe:
3447 case Builtin::BIwork_group_commit_read_pipe:
3448 case Builtin::BIwork_group_commit_write_pipe:
3449 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3452 case Builtin::BIsub_group_commit_read_pipe:
3453 case Builtin::BIsub_group_commit_write_pipe:
3454 if (
OpenCL().checkSubgroupExt(TheCall) ||
3455 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3458 case Builtin::BIget_pipe_num_packets:
3459 case Builtin::BIget_pipe_max_packets:
3460 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3463 case Builtin::BIto_global:
3464 case Builtin::BIto_local:
3465 case Builtin::BIto_private:
3466 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3470 case Builtin::BIenqueue_kernel:
3471 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3474 case Builtin::BIget_kernel_work_group_size:
3475 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3476 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3479 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3480 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3481 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3484 case Builtin::BI__builtin_os_log_format:
3485 Cleanup.setExprNeedsCleanups(
true);
3487 case Builtin::BI__builtin_os_log_format_buffer_size:
3488 if (BuiltinOSLogFormat(TheCall))
3491 case Builtin::BI__builtin_frame_address:
3492 case Builtin::BI__builtin_return_address: {
3501 Result.Val.getInt() != 0)
3503 << ((BuiltinID == Builtin::BI__builtin_return_address)
3504 ?
"__builtin_return_address"
3505 :
"__builtin_frame_address")
3510 case Builtin::BI__builtin_nondeterministic_value: {
3511 if (BuiltinNonDeterministicValue(TheCall))
3518 case Builtin::BI__builtin_elementwise_abs:
3526 case Builtin::BI__builtin_elementwise_acos:
3527 case Builtin::BI__builtin_elementwise_asin:
3528 case Builtin::BI__builtin_elementwise_atan:
3529 case Builtin::BI__builtin_elementwise_ceil:
3530 case Builtin::BI__builtin_elementwise_cos:
3531 case Builtin::BI__builtin_elementwise_cosh:
3532 case Builtin::BI__builtin_elementwise_exp:
3533 case Builtin::BI__builtin_elementwise_exp2:
3534 case Builtin::BI__builtin_elementwise_exp10:
3535 case Builtin::BI__builtin_elementwise_floor:
3536 case Builtin::BI__builtin_elementwise_log:
3537 case Builtin::BI__builtin_elementwise_log2:
3538 case Builtin::BI__builtin_elementwise_log10:
3539 case Builtin::BI__builtin_elementwise_roundeven:
3540 case Builtin::BI__builtin_elementwise_round:
3541 case Builtin::BI__builtin_elementwise_rint:
3542 case Builtin::BI__builtin_elementwise_nearbyint:
3543 case Builtin::BI__builtin_elementwise_sin:
3544 case Builtin::BI__builtin_elementwise_sinh:
3545 case Builtin::BI__builtin_elementwise_sqrt:
3546 case Builtin::BI__builtin_elementwise_tan:
3547 case Builtin::BI__builtin_elementwise_tanh:
3548 case Builtin::BI__builtin_elementwise_trunc:
3549 case Builtin::BI__builtin_elementwise_canonicalize:
3554 case Builtin::BI__builtin_elementwise_fma:
3559 case Builtin::BI__builtin_elementwise_ldexp: {
3581 const auto *Vec0 = TyA->
getAs<VectorType>();
3582 const auto *Vec1 = TyExp->
getAs<VectorType>();
3583 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3585 if (Arg0Length != Arg1Length) {
3587 diag::err_typecheck_vector_lengths_not_equal)
3601 case Builtin::BI__builtin_elementwise_minnum:
3602 case Builtin::BI__builtin_elementwise_maxnum:
3603 case Builtin::BI__builtin_elementwise_minimum:
3604 case Builtin::BI__builtin_elementwise_maximum:
3605 case Builtin::BI__builtin_elementwise_minimumnum:
3606 case Builtin::BI__builtin_elementwise_maximumnum:
3607 case Builtin::BI__builtin_elementwise_atan2:
3608 case Builtin::BI__builtin_elementwise_fmod:
3609 case Builtin::BI__builtin_elementwise_pow:
3610 if (BuiltinElementwiseMath(TheCall,
3616 case Builtin::BI__builtin_elementwise_add_sat:
3617 case Builtin::BI__builtin_elementwise_sub_sat:
3618 if (BuiltinElementwiseMath(TheCall,
3622 case Builtin::BI__builtin_elementwise_fshl:
3623 case Builtin::BI__builtin_elementwise_fshr:
3628 case Builtin::BI__builtin_elementwise_min:
3629 case Builtin::BI__builtin_elementwise_max: {
3630 if (BuiltinElementwiseMath(TheCall))
3632 Expr *Arg0 = TheCall->
getArg(0);
3633 Expr *Arg1 = TheCall->
getArg(1);
3634 QualType Ty0 = Arg0->
getType();
3635 QualType Ty1 = Arg1->
getType();
3636 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3637 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3640 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3641 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3642 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3645 case Builtin::BI__builtin_elementwise_popcount:
3646 case Builtin::BI__builtin_elementwise_bitreverse:
3651 case Builtin::BI__builtin_elementwise_copysign: {
3660 QualType MagnitudeTy = Magnitude.
get()->
getType();
3673 diag::err_typecheck_call_different_arg_types)
3674 << MagnitudeTy << SignTy;
3682 case Builtin::BI__builtin_elementwise_clzg:
3683 case Builtin::BI__builtin_elementwise_ctzg:
3691 }
else if (BuiltinElementwiseMath(
3695 case Builtin::BI__builtin_reduce_max:
3696 case Builtin::BI__builtin_reduce_min: {
3697 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3700 const Expr *Arg = TheCall->
getArg(0);
3705 ElTy = TyA->getElementType();
3709 if (ElTy.isNull()) {
3719 case Builtin::BI__builtin_reduce_maximum:
3720 case Builtin::BI__builtin_reduce_minimum: {
3721 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3724 const Expr *Arg = TheCall->
getArg(0);
3729 ElTy = TyA->getElementType();
3733 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3746 case Builtin::BI__builtin_reduce_add:
3747 case Builtin::BI__builtin_reduce_mul:
3748 case Builtin::BI__builtin_reduce_xor:
3749 case Builtin::BI__builtin_reduce_or:
3750 case Builtin::BI__builtin_reduce_and: {
3751 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3754 const Expr *Arg = TheCall->
getArg(0);
3768 case Builtin::BI__builtin_reduce_assoc_fadd:
3769 case Builtin::BI__builtin_reduce_in_order_fadd: {
3771 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3796 diag::err_builtin_invalid_arg_type)
3808 case Builtin::BI__builtin_matrix_transpose:
3809 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3811 case Builtin::BI__builtin_matrix_column_major_load:
3812 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3814 case Builtin::BI__builtin_matrix_column_major_store:
3815 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3817 case Builtin::BI__builtin_verbose_trap:
3822 case Builtin::BI__builtin_get_device_side_mangled_name: {
3823 auto Check = [](CallExpr *TheCall) {
3829 auto *D = DRE->getDecl();
3832 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3833 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3835 if (!Check(TheCall)) {
3837 diag::err_hip_invalid_args_builtin_mangled_name);
3842 case Builtin::BI__builtin_bswapg:
3846 case Builtin::BI__builtin_bitreverseg:
3850 case Builtin::BI__builtin_popcountg:
3854 case Builtin::BI__builtin_clzg:
3855 case Builtin::BI__builtin_ctzg:
3860 case Builtin::BI__builtin_stdc_rotate_left:
3861 case Builtin::BI__builtin_stdc_rotate_right:
3866 case Builtin::BI__builtin_stdc_bit_floor:
3867 case Builtin::BI__builtin_stdc_bit_ceil:
3868 case Builtin::BIstdc_bit_floor:
3869 case Builtin::BIstdc_bit_ceil:
3873 case Builtin::BI__builtin_stdc_has_single_bit:
3874 case Builtin::BIstdc_has_single_bit:
3878 case Builtin::BI__builtin_stdc_leading_zeros:
3879 case Builtin::BI__builtin_stdc_leading_ones:
3880 case Builtin::BI__builtin_stdc_trailing_zeros:
3881 case Builtin::BI__builtin_stdc_trailing_ones:
3882 case Builtin::BI__builtin_stdc_first_leading_zero:
3883 case Builtin::BI__builtin_stdc_first_leading_one:
3884 case Builtin::BI__builtin_stdc_first_trailing_zero:
3885 case Builtin::BI__builtin_stdc_first_trailing_one:
3886 case Builtin::BI__builtin_stdc_count_zeros:
3887 case Builtin::BI__builtin_stdc_count_ones:
3888 case Builtin::BI__builtin_stdc_bit_width:
3889 case Builtin::BIstdc_leading_zeros:
3890 case Builtin::BIstdc_leading_ones:
3891 case Builtin::BIstdc_trailing_zeros:
3892 case Builtin::BIstdc_trailing_ones:
3893 case Builtin::BIstdc_first_leading_zero:
3894 case Builtin::BIstdc_first_leading_one:
3895 case Builtin::BIstdc_first_trailing_zero:
3896 case Builtin::BIstdc_first_trailing_one:
3897 case Builtin::BIstdc_count_zeros:
3898 case Builtin::BIstdc_count_ones:
3899 case Builtin::BIstdc_bit_width:
3904 case Builtin::BI__builtin_allow_runtime_check: {
3905 Expr *Arg = TheCall->
getArg(0);
3915 case Builtin::BI__builtin_allow_sanitize_check: {
3919 Expr *Arg = TheCall->
getArg(0);
3921 const StringLiteral *SanitizerName =
3923 if (!SanitizerName) {
3929 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3930 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3931 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3935 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3941 case Builtin::BI__builtin_counted_by_ref:
3942 if (BuiltinCountedByRef(TheCall))
3952 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3953 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3954 assert(
Context.getAuxTargetInfo() &&
3955 "Aux Target Builtin, but not an aux target?");
3957 if (CheckTSBuiltinFunctionCall(
3959 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3962 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3968 return TheCallResult;
3983 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3987 diag::err_argument_not_contiguous_bit_field)
3994 bool IsVariadic =
false;
3997 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3998 IsVariadic = BD->isVariadic();
3999 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4000 IsVariadic = OMD->isVariadic();
4007 bool HasImplicitThisParam,
bool IsVariadic,
4011 else if (IsVariadic)
4021 if (HasImplicitThisParam) {
4053 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4054 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4055 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4056 Expr = ILE->getInit(0);
4066 const Expr *ArgExpr,
4070 S.
PDiag(diag::warn_null_arg)
4076 if (
auto nullability =
type->getNullability())
4087 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4093 llvm::SmallBitVector NonNullArgs;
4099 for (
const auto *Arg : Args)
4106 unsigned IdxAST = Idx.getASTIndex();
4107 if (IdxAST >= Args.size())
4109 if (NonNullArgs.empty())
4110 NonNullArgs.resize(Args.size());
4111 NonNullArgs.set(IdxAST);
4120 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4125 unsigned ParamIndex = 0;
4127 I != E; ++I, ++ParamIndex) {
4130 if (NonNullArgs.empty())
4131 NonNullArgs.resize(Args.size());
4133 NonNullArgs.set(ParamIndex);
4140 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4145 type = blockType->getPointeeType();
4159 if (NonNullArgs.empty())
4160 NonNullArgs.resize(Args.size());
4162 NonNullArgs.set(Index);
4171 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4172 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4173 if (NonNullArgs[ArgIndex])
4179 StringRef ParamName,
QualType ArgTy,
4202 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4203 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4207 if (ArgAlign < ParamAlign)
4208 Diag(Loc, diag::warn_param_mismatched_alignment)
4210 << ParamName << (FDecl !=
nullptr) << FDecl;
4214 const Expr *ThisArg,
4216 if (!FD || Args.empty())
4218 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4219 if (Idx == LifetimeCaptureByAttr::Global ||
4220 Idx == LifetimeCaptureByAttr::Unknown)
4222 if (IsMemberFunction && Idx == 0)
4224 return Args[Idx - IsMemberFunction];
4226 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4231 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4232 for (
int CapturingParamIdx :
Attr->params()) {
4235 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4238 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4246 I + IsMemberFunction);
4248 if (IsMemberFunction) {
4256 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4266 llvm::any_of(Args, [](
const Expr *E) {
4267 return E && E->isInstantiationDependent();
4272 llvm::SmallBitVector CheckedVarArgs;
4274 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4276 CheckedVarArgs.resize(Args.size());
4277 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4282 CheckedVarArgs.resize(Args.size());
4283 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4290 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4294 : isa_and_nonnull<FunctionDecl>(FDecl)
4296 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4300 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4302 if (
const Expr *Arg = Args[ArgIdx]) {
4303 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4310 if (FDecl || Proto) {
4315 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4316 CheckArgumentWithTypeTag(I, Args, Loc);
4322 if (!Proto && FDecl) {
4324 if (isa_and_nonnull<FunctionProtoType>(FT))
4330 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4332 bool IsScalableArg =
false;
4333 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4335 if (
const Expr *Arg = Args[ArgIdx]) {
4339 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4347 IsScalableArg =
true;
4349 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4358 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4359 llvm::StringMap<bool> CallerFeatureMap;
4360 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4361 if (!CallerFeatureMap.contains(
"sme"))
4362 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4363 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4364 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4373 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4375 (IsScalableArg || IsScalableRet)) {
4376 bool IsCalleeStreaming =
4378 bool IsCalleeStreamingCompatible =
4382 if (!IsCalleeStreamingCompatible &&
4386 unsigned VL = LO.VScaleMin * 128;
4387 unsigned SVL = LO.VScaleStreamingMin * 128;
4388 bool IsVLMismatch = VL && SVL && VL != SVL;
4390 auto EmitDiag = [&](
bool IsArg) {
4394 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4395 << IsArg << IsCalleeStreaming << SVL << VL;
4398 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4399 << IsArg << SVL << VL;
4401 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4418 bool CallerHasZAState =
false;
4419 bool CallerHasZT0State =
false;
4421 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4423 CallerHasZAState =
true;
4425 CallerHasZT0State =
true;
4429 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4431 CallerHasZT0State |=
4433 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4439 Diag(Loc, diag::err_sme_za_call_no_za_state);
4442 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4446 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4447 Diag(Loc, diag::note_sme_use_preserves_za);
4452 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4453 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4454 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4455 if (!Arg->isValueDependent()) {
4457 if (Arg->EvaluateAsInt(Align,
Context)) {
4458 const llvm::APSInt &I = Align.
Val.
getInt();
4459 if (!I.isPowerOf2())
4460 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4461 << Arg->getSourceRange();
4464 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4473 << diag::OffloadLang::SYCL;
4495 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4496 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4498 checkCall(FDecl, Proto,
nullptr, Args,
true,
4507 IsMemberOperatorCall;
4513 Expr *ImplicitThis =
nullptr;
4518 ImplicitThis = Args[0];
4521 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4532 ThisType =
Context.getPointerType(ThisType);
4538 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4556 CheckAbsoluteValueFunction(TheCall, FDecl);
4557 CheckMaxUnsignedZero(TheCall, FDecl);
4558 CheckInfNaNFunction(TheCall, FDecl);
4569 case Builtin::BIstrlcpy:
4570 case Builtin::BIstrlcat:
4571 CheckStrlcpycatArguments(TheCall, FnInfo);
4573 case Builtin::BIstrncat:
4574 CheckStrncatArguments(TheCall, FnInfo);
4576 case Builtin::BIfree:
4577 CheckFreeArguments(TheCall);
4580 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4589 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4590 Ty =
V->getType().getNonReferenceType();
4591 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4592 Ty = F->getType().getNonReferenceType();
4629 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4632 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4634 case AtomicExpr::AO__c11_atomic_init:
4635 case AtomicExpr::AO__opencl_atomic_init:
4636 llvm_unreachable(
"There is no ordering argument for an init");
4638 case AtomicExpr::AO__c11_atomic_load:
4639 case AtomicExpr::AO__opencl_atomic_load:
4640 case AtomicExpr::AO__hip_atomic_load:
4641 case AtomicExpr::AO__atomic_load_n:
4642 case AtomicExpr::AO__atomic_load:
4643 case AtomicExpr::AO__scoped_atomic_load_n:
4644 case AtomicExpr::AO__scoped_atomic_load:
4645 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4646 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4648 case AtomicExpr::AO__c11_atomic_store:
4649 case AtomicExpr::AO__opencl_atomic_store:
4650 case AtomicExpr::AO__hip_atomic_store:
4651 case AtomicExpr::AO__atomic_store:
4652 case AtomicExpr::AO__atomic_store_n:
4653 case AtomicExpr::AO__scoped_atomic_store:
4654 case AtomicExpr::AO__scoped_atomic_store_n:
4655 case AtomicExpr::AO__atomic_clear:
4656 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4657 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4658 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4688#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4689 case AtomicExpr::AO__hip_atomic_##hip: \
4690 OldName = "__hip_atomic_" #hip; \
4691 NewName = "__scoped_atomic_" #scoped; \
4704#undef HIP_ATOMIC_FIXABLE
4705 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4706 OldName =
"__hip_atomic_compare_exchange_weak";
4707 NewName =
"__scoped_atomic_compare_exchange";
4710 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4711 OldName =
"__hip_atomic_compare_exchange_strong";
4712 NewName =
"__scoped_atomic_compare_exchange";
4716 llvm_unreachable(
"unhandled HIP atomic op");
4719 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4720 << OldName << NewName;
4727 std::optional<llvm::APSInt> ScopeVal =
4732 StringRef ScopeName;
4733 switch (ScopeVal->getZExtValue()) {
4735 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4738 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4741 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4744 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4747 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4750 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
4802 const unsigned NumForm = ClearByte + 1;
4803 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4804 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4812 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4813 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4814 "need to update code for modified forms");
4815 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4816 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4817 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4818 "need to update code for modified C11 atomics");
4819 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4820 Op <= AtomicExpr::AO__opencl_atomic_store;
4821 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4822 Op <= AtomicExpr::AO__hip_atomic_store;
4823 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4824 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4825 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4826 Op <= AtomicExpr::AO__c11_atomic_store) ||
4828 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4829 Op == AtomicExpr::AO__atomic_store_n ||
4830 Op == AtomicExpr::AO__atomic_exchange_n ||
4831 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4832 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4833 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4834 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4835 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4839 enum ArithOpExtraValueType {
4844 unsigned ArithAllows = AOEVT_None;
4847 case AtomicExpr::AO__c11_atomic_init:
4848 case AtomicExpr::AO__opencl_atomic_init:
4852 case AtomicExpr::AO__c11_atomic_load:
4853 case AtomicExpr::AO__opencl_atomic_load:
4854 case AtomicExpr::AO__hip_atomic_load:
4855 case AtomicExpr::AO__atomic_load_n:
4856 case AtomicExpr::AO__scoped_atomic_load_n:
4857 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4861 case AtomicExpr::AO__atomic_load:
4862 case AtomicExpr::AO__scoped_atomic_load:
4863 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4867 case AtomicExpr::AO__c11_atomic_store:
4868 case AtomicExpr::AO__opencl_atomic_store:
4869 case AtomicExpr::AO__hip_atomic_store:
4870 case AtomicExpr::AO__atomic_store:
4871 case AtomicExpr::AO__atomic_store_n:
4872 case AtomicExpr::AO__scoped_atomic_store:
4873 case AtomicExpr::AO__scoped_atomic_store_n:
4874 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4877 case AtomicExpr::AO__atomic_fetch_add:
4878 case AtomicExpr::AO__atomic_fetch_sub:
4879 case AtomicExpr::AO__atomic_add_fetch:
4880 case AtomicExpr::AO__atomic_sub_fetch:
4881 case AtomicExpr::AO__scoped_atomic_fetch_add:
4882 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4883 case AtomicExpr::AO__scoped_atomic_add_fetch:
4884 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4885 case AtomicExpr::AO__c11_atomic_fetch_add:
4886 case AtomicExpr::AO__c11_atomic_fetch_sub:
4887 case AtomicExpr::AO__opencl_atomic_fetch_add:
4888 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4889 case AtomicExpr::AO__hip_atomic_fetch_add:
4890 case AtomicExpr::AO__hip_atomic_fetch_sub:
4891 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4894 case AtomicExpr::AO__atomic_fetch_max:
4895 case AtomicExpr::AO__atomic_fetch_min:
4896 case AtomicExpr::AO__atomic_max_fetch:
4897 case AtomicExpr::AO__atomic_min_fetch:
4898 case AtomicExpr::AO__scoped_atomic_fetch_max:
4899 case AtomicExpr::AO__scoped_atomic_fetch_min:
4900 case AtomicExpr::AO__scoped_atomic_max_fetch:
4901 case AtomicExpr::AO__scoped_atomic_min_fetch:
4902 case AtomicExpr::AO__c11_atomic_fetch_max:
4903 case AtomicExpr::AO__c11_atomic_fetch_min:
4904 case AtomicExpr::AO__opencl_atomic_fetch_max:
4905 case AtomicExpr::AO__opencl_atomic_fetch_min:
4906 case AtomicExpr::AO__hip_atomic_fetch_max:
4907 case AtomicExpr::AO__hip_atomic_fetch_min:
4908 ArithAllows = AOEVT_FP;
4911 case AtomicExpr::AO__c11_atomic_fetch_and:
4912 case AtomicExpr::AO__c11_atomic_fetch_or:
4913 case AtomicExpr::AO__c11_atomic_fetch_xor:
4914 case AtomicExpr::AO__hip_atomic_fetch_and:
4915 case AtomicExpr::AO__hip_atomic_fetch_or:
4916 case AtomicExpr::AO__hip_atomic_fetch_xor:
4917 case AtomicExpr::AO__c11_atomic_fetch_nand:
4918 case AtomicExpr::AO__opencl_atomic_fetch_and:
4919 case AtomicExpr::AO__opencl_atomic_fetch_or:
4920 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4921 case AtomicExpr::AO__atomic_fetch_and:
4922 case AtomicExpr::AO__atomic_fetch_or:
4923 case AtomicExpr::AO__atomic_fetch_xor:
4924 case AtomicExpr::AO__atomic_fetch_nand:
4925 case AtomicExpr::AO__atomic_and_fetch:
4926 case AtomicExpr::AO__atomic_or_fetch:
4927 case AtomicExpr::AO__atomic_xor_fetch:
4928 case AtomicExpr::AO__atomic_nand_fetch:
4929 case AtomicExpr::AO__atomic_fetch_uinc:
4930 case AtomicExpr::AO__atomic_fetch_udec:
4931 case AtomicExpr::AO__scoped_atomic_fetch_and:
4932 case AtomicExpr::AO__scoped_atomic_fetch_or:
4933 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4934 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4935 case AtomicExpr::AO__scoped_atomic_and_fetch:
4936 case AtomicExpr::AO__scoped_atomic_or_fetch:
4937 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4938 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4939 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
4940 case AtomicExpr::AO__scoped_atomic_fetch_udec:
4944 case AtomicExpr::AO__c11_atomic_exchange:
4945 case AtomicExpr::AO__hip_atomic_exchange:
4946 case AtomicExpr::AO__opencl_atomic_exchange:
4947 case AtomicExpr::AO__atomic_exchange_n:
4948 case AtomicExpr::AO__scoped_atomic_exchange_n:
4949 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4953 case AtomicExpr::AO__atomic_exchange:
4954 case AtomicExpr::AO__scoped_atomic_exchange:
4955 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4959 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4960 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4961 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4962 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4963 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4964 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4968 case AtomicExpr::AO__atomic_compare_exchange:
4969 case AtomicExpr::AO__atomic_compare_exchange_n:
4970 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4971 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4972 ArithAllows = AOEVT_Pointer;
4976 case AtomicExpr::AO__atomic_test_and_set:
4977 Form = TestAndSetByte;
4980 case AtomicExpr::AO__atomic_clear:
4985 unsigned AdjustedNumArgs = NumArgs[Form];
4986 if ((IsOpenCL || IsHIP || IsScoped) &&
4987 Op != AtomicExpr::AO__opencl_atomic_init)
4990 if (Args.size() < AdjustedNumArgs) {
4991 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4992 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4995 }
else if (Args.size() > AdjustedNumArgs) {
4996 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4997 diag::err_typecheck_call_too_many_args)
4998 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5004 Expr *Ptr = Args[0];
5009 Ptr = ConvertedPtr.
get();
5012 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5022 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5028 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5034 }
else if (Form != Load && Form != LoadCopy) {
5036 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5042 if (Form != TestAndSetByte && Form != ClearByte) {
5045 diag::err_incomplete_type))
5048 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5049 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5059 pointerType->getPointeeType().getCVRQualifiers());
5069 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5079 auto IsAllowedValueType = [&](
QualType ValType,
5080 unsigned AllowedType) ->
bool {
5081 bool IsX87LongDouble =
5083 &
Context.getTargetInfo().getLongDoubleFormat() ==
5084 &llvm::APFloat::x87DoubleExtended();
5088 return AllowedType & AOEVT_Pointer;
5092 if (IsX87LongDouble)
5096 if (!IsAllowedValueType(ValType, ArithAllows)) {
5097 auto DID = ArithAllows & AOEVT_FP
5098 ? (ArithAllows & AOEVT_Pointer
5099 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5100 : diag::err_atomic_op_needs_atomic_int_or_fp)
5101 : (ArithAllows & AOEVT_Pointer
5102 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5103 : diag::err_atomic_op_needs_atomic_int);
5110 diag::err_incomplete_type)) {
5121 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5137 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5149 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5152 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5158 bool IsPassedByAddress =
false;
5159 if (!IsC11 && !IsHIP && !IsN) {
5161 IsPassedByAddress =
true;
5166 APIOrderedArgs.push_back(Args[0]);
5170 APIOrderedArgs.push_back(Args[1]);
5176 APIOrderedArgs.push_back(Args[2]);
5177 APIOrderedArgs.push_back(Args[1]);
5180 APIOrderedArgs.push_back(Args[2]);
5181 APIOrderedArgs.push_back(Args[3]);
5182 APIOrderedArgs.push_back(Args[1]);
5185 APIOrderedArgs.push_back(Args[2]);
5186 APIOrderedArgs.push_back(Args[4]);
5187 APIOrderedArgs.push_back(Args[1]);
5188 APIOrderedArgs.push_back(Args[3]);
5191 APIOrderedArgs.push_back(Args[2]);
5192 APIOrderedArgs.push_back(Args[4]);
5193 APIOrderedArgs.push_back(Args[5]);
5194 APIOrderedArgs.push_back(Args[1]);
5195 APIOrderedArgs.push_back(Args[3]);
5197 case TestAndSetByte:
5199 APIOrderedArgs.push_back(Args[1]);
5203 APIOrderedArgs.append(Args.begin(), Args.end());
5210 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5212 if (i < NumVals[Form] + 1) {
5225 assert(Form != Load);
5227 Ty =
Context.getPointerDiffType();
5230 else if (Form ==
Copy || Form == Xchg) {
5231 if (IsPassedByAddress) {
5238 Expr *ValArg = APIOrderedArgs[i];
5245 AS = PtrTy->getPointeeType().getAddressSpace();
5254 if (IsPassedByAddress)
5274 APIOrderedArgs[i] = Arg.
get();
5279 SubExprs.push_back(Ptr);
5283 SubExprs.push_back(APIOrderedArgs[1]);
5286 case TestAndSetByte:
5288 SubExprs.push_back(APIOrderedArgs[1]);
5294 SubExprs.push_back(APIOrderedArgs[2]);
5295 SubExprs.push_back(APIOrderedArgs[1]);
5299 SubExprs.push_back(APIOrderedArgs[3]);
5300 SubExprs.push_back(APIOrderedArgs[1]);
5301 SubExprs.push_back(APIOrderedArgs[2]);
5304 SubExprs.push_back(APIOrderedArgs[3]);
5305 SubExprs.push_back(APIOrderedArgs[1]);
5306 SubExprs.push_back(APIOrderedArgs[4]);
5307 SubExprs.push_back(APIOrderedArgs[2]);
5310 SubExprs.push_back(APIOrderedArgs[4]);
5311 SubExprs.push_back(APIOrderedArgs[1]);
5312 SubExprs.push_back(APIOrderedArgs[5]);
5313 SubExprs.push_back(APIOrderedArgs[2]);
5314 SubExprs.push_back(APIOrderedArgs[3]);
5319 if (SubExprs.size() >= 2 && Form !=
Init) {
5320 std::optional<llvm::APSInt>
Success =
5321 SubExprs[1]->getIntegerConstantExpr(
Context);
5323 Diag(SubExprs[1]->getBeginLoc(),
5324 diag::warn_atomic_op_has_invalid_memory_order)
5325 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5326 << SubExprs[1]->getSourceRange();
5328 if (SubExprs.size() >= 5) {
5329 if (std::optional<llvm::APSInt>
Failure =
5330 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5331 if (!llvm::is_contained(
5332 {llvm::AtomicOrderingCABI::relaxed,
5333 llvm::AtomicOrderingCABI::consume,
5334 llvm::AtomicOrderingCABI::acquire,
5335 llvm::AtomicOrderingCABI::seq_cst},
5336 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5337 Diag(SubExprs[3]->getBeginLoc(),
5338 diag::warn_atomic_op_has_invalid_memory_order)
5339 << 2 << SubExprs[3]->getSourceRange();
5346 auto *
Scope = Args[Args.size() - 1];
5347 if (std::optional<llvm::APSInt>
Result =
5349 if (!ScopeModel->isValid(
Result->getZExtValue()))
5350 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5351 <<
Scope->getSourceRange();
5353 SubExprs.push_back(
Scope);
5362 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5363 Op == AtomicExpr::AO__c11_atomic_store ||
5364 Op == AtomicExpr::AO__opencl_atomic_load ||
5365 Op == AtomicExpr::AO__hip_atomic_load ||
5366 Op == AtomicExpr::AO__opencl_atomic_store ||
5367 Op == AtomicExpr::AO__hip_atomic_store) &&
5368 Context.AtomicUsesUnsupportedLibcall(AE))
5370 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5371 Op == AtomicExpr::AO__opencl_atomic_load ||
5372 Op == AtomicExpr::AO__hip_atomic_load)
5377 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5393 assert(Fn &&
"builtin call without direct callee!");
5409 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5416 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5418 <<
Callee->getSourceRange();
5427 Expr *FirstArg = TheCall->
getArg(0);
5431 FirstArg = FirstArgResult.
get();
5432 TheCall->
setArg(0, FirstArg);
5444 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5451 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5481 QualType ResultType = ValType;
5486#define BUILTIN_ROW(x) \
5487 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5488 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5490 static const unsigned BuiltinIndices[][5] = {
5515 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5516 case 1: SizeIndex = 0;
break;
5517 case 2: SizeIndex = 1;
break;
5518 case 4: SizeIndex = 2;
break;
5519 case 8: SizeIndex = 3;
break;
5520 case 16: SizeIndex = 4;
break;
5532 unsigned BuiltinIndex, NumFixed = 1;
5533 bool WarnAboutSemanticsChange =
false;
5534 switch (BuiltinID) {
5535 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5536 case Builtin::BI__sync_fetch_and_add:
5537 case Builtin::BI__sync_fetch_and_add_1:
5538 case Builtin::BI__sync_fetch_and_add_2:
5539 case Builtin::BI__sync_fetch_and_add_4:
5540 case Builtin::BI__sync_fetch_and_add_8:
5541 case Builtin::BI__sync_fetch_and_add_16:
5545 case Builtin::BI__sync_fetch_and_sub:
5546 case Builtin::BI__sync_fetch_and_sub_1:
5547 case Builtin::BI__sync_fetch_and_sub_2:
5548 case Builtin::BI__sync_fetch_and_sub_4:
5549 case Builtin::BI__sync_fetch_and_sub_8:
5550 case Builtin::BI__sync_fetch_and_sub_16:
5554 case Builtin::BI__sync_fetch_and_or:
5555 case Builtin::BI__sync_fetch_and_or_1:
5556 case Builtin::BI__sync_fetch_and_or_2:
5557 case Builtin::BI__sync_fetch_and_or_4:
5558 case Builtin::BI__sync_fetch_and_or_8:
5559 case Builtin::BI__sync_fetch_and_or_16:
5563 case Builtin::BI__sync_fetch_and_and:
5564 case Builtin::BI__sync_fetch_and_and_1:
5565 case Builtin::BI__sync_fetch_and_and_2:
5566 case Builtin::BI__sync_fetch_and_and_4:
5567 case Builtin::BI__sync_fetch_and_and_8:
5568 case Builtin::BI__sync_fetch_and_and_16:
5572 case Builtin::BI__sync_fetch_and_xor:
5573 case Builtin::BI__sync_fetch_and_xor_1:
5574 case Builtin::BI__sync_fetch_and_xor_2:
5575 case Builtin::BI__sync_fetch_and_xor_4:
5576 case Builtin::BI__sync_fetch_and_xor_8:
5577 case Builtin::BI__sync_fetch_and_xor_16:
5581 case Builtin::BI__sync_fetch_and_nand:
5582 case Builtin::BI__sync_fetch_and_nand_1:
5583 case Builtin::BI__sync_fetch_and_nand_2:
5584 case Builtin::BI__sync_fetch_and_nand_4:
5585 case Builtin::BI__sync_fetch_and_nand_8:
5586 case Builtin::BI__sync_fetch_and_nand_16:
5588 WarnAboutSemanticsChange =
true;
5591 case Builtin::BI__sync_add_and_fetch:
5592 case Builtin::BI__sync_add_and_fetch_1:
5593 case Builtin::BI__sync_add_and_fetch_2:
5594 case Builtin::BI__sync_add_and_fetch_4:
5595 case Builtin::BI__sync_add_and_fetch_8:
5596 case Builtin::BI__sync_add_and_fetch_16:
5600 case Builtin::BI__sync_sub_and_fetch:
5601 case Builtin::BI__sync_sub_and_fetch_1:
5602 case Builtin::BI__sync_sub_and_fetch_2:
5603 case Builtin::BI__sync_sub_and_fetch_4:
5604 case Builtin::BI__sync_sub_and_fetch_8:
5605 case Builtin::BI__sync_sub_and_fetch_16:
5609 case Builtin::BI__sync_and_and_fetch:
5610 case Builtin::BI__sync_and_and_fetch_1:
5611 case Builtin::BI__sync_and_and_fetch_2:
5612 case Builtin::BI__sync_and_and_fetch_4:
5613 case Builtin::BI__sync_and_and_fetch_8:
5614 case Builtin::BI__sync_and_and_fetch_16:
5618 case Builtin::BI__sync_or_and_fetch:
5619 case Builtin::BI__sync_or_and_fetch_1:
5620 case Builtin::BI__sync_or_and_fetch_2:
5621 case Builtin::BI__sync_or_and_fetch_4:
5622 case Builtin::BI__sync_or_and_fetch_8:
5623 case Builtin::BI__sync_or_and_fetch_16:
5627 case Builtin::BI__sync_xor_and_fetch:
5628 case Builtin::BI__sync_xor_and_fetch_1:
5629 case Builtin::BI__sync_xor_and_fetch_2:
5630 case Builtin::BI__sync_xor_and_fetch_4:
5631 case Builtin::BI__sync_xor_and_fetch_8:
5632 case Builtin::BI__sync_xor_and_fetch_16:
5636 case Builtin::BI__sync_nand_and_fetch:
5637 case Builtin::BI__sync_nand_and_fetch_1:
5638 case Builtin::BI__sync_nand_and_fetch_2:
5639 case Builtin::BI__sync_nand_and_fetch_4:
5640 case Builtin::BI__sync_nand_and_fetch_8:
5641 case Builtin::BI__sync_nand_and_fetch_16:
5643 WarnAboutSemanticsChange =
true;
5646 case Builtin::BI__sync_val_compare_and_swap:
5647 case Builtin::BI__sync_val_compare_and_swap_1:
5648 case Builtin::BI__sync_val_compare_and_swap_2:
5649 case Builtin::BI__sync_val_compare_and_swap_4:
5650 case Builtin::BI__sync_val_compare_and_swap_8:
5651 case Builtin::BI__sync_val_compare_and_swap_16:
5656 case Builtin::BI__sync_bool_compare_and_swap:
5657 case Builtin::BI__sync_bool_compare_and_swap_1:
5658 case Builtin::BI__sync_bool_compare_and_swap_2:
5659 case Builtin::BI__sync_bool_compare_and_swap_4:
5660 case Builtin::BI__sync_bool_compare_and_swap_8:
5661 case Builtin::BI__sync_bool_compare_and_swap_16:
5667 case Builtin::BI__sync_lock_test_and_set:
5668 case Builtin::BI__sync_lock_test_and_set_1:
5669 case Builtin::BI__sync_lock_test_and_set_2:
5670 case Builtin::BI__sync_lock_test_and_set_4:
5671 case Builtin::BI__sync_lock_test_and_set_8:
5672 case Builtin::BI__sync_lock_test_and_set_16:
5676 case Builtin::BI__sync_lock_release:
5677 case Builtin::BI__sync_lock_release_1:
5678 case Builtin::BI__sync_lock_release_2:
5679 case Builtin::BI__sync_lock_release_4:
5680 case Builtin::BI__sync_lock_release_8:
5681 case Builtin::BI__sync_lock_release_16:
5687 case Builtin::BI__sync_swap:
5688 case Builtin::BI__sync_swap_1:
5689 case Builtin::BI__sync_swap_2:
5690 case Builtin::BI__sync_swap_4:
5691 case Builtin::BI__sync_swap_8:
5692 case Builtin::BI__sync_swap_16:
5700 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5701 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5702 <<
Callee->getSourceRange();
5706 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5707 <<
Callee->getSourceRange();
5709 if (WarnAboutSemanticsChange) {
5710 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5711 <<
Callee->getSourceRange();
5716 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5717 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5718 FunctionDecl *NewBuiltinDecl;
5719 if (NewBuiltinID == BuiltinID)
5720 NewBuiltinDecl = FDecl;
5723 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5726 assert(Res.getFoundDecl());
5727 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5728 if (!NewBuiltinDecl)
5735 for (
unsigned i = 0; i != NumFixed; ++i) {
5764 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5766 CK_BuiltinFnToFnPtr);
5777 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5778 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5779 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5783 return TheCallResult;
5787 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5792 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5793 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5794 "Unexpected nontemporal load/store builtin!");
5795 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5796 unsigned numArgs = isStore ? 2 : 1;
5806 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5812 PointerArg = PointerArgResult.
get();
5813 TheCall->
setArg(numArgs - 1, PointerArg);
5817 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5830 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5837 return TheCallResult;
5849 return TheCallResult;
5856 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5858 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5859 Literal = ObjcLiteral->getString();
5863 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5870 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5871 InitializedEntity Entity =
5881 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5882 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5883 TT.getArch() == llvm::Triple::aarch64_32);
5884 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5885 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5886 if (IsX64 || IsAArch64) {
5893 return S.
Diag(Fn->getBeginLoc(),
5894 diag::err_ms_va_start_used_in_sysv_function);
5901 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5902 return S.
Diag(Fn->getBeginLoc(),
5903 diag::err_va_start_used_in_wrong_abi_function)
5904 << !IsWindowsOrUEFI;
5910 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5918 bool IsVariadic =
false;
5921 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5922 IsVariadic =
Block->isVariadic();
5923 Params =
Block->parameters();
5924 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5927 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5928 IsVariadic = MD->isVariadic();
5930 Params = MD->parameters();
5933 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5937 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5942 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5947 *LastParam = Params.empty() ?
nullptr : Params.back();
5952bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5957 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5981 ParmVarDecl *LastParam;
5992 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5994 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5999 if (std::optional<llvm::APSInt> Val =
6001 Val &&
LangOpts.C23 && *Val == 0 &&
6002 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6003 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6010 SourceLocation ParamLoc;
6011 bool IsCRegister =
false;
6012 bool SecondArgIsLastNonVariadicArgument =
false;
6013 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6014 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6015 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6018 ParamLoc = PV->getLocation();
6024 if (!SecondArgIsLastNonVariadicArgument)
6026 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6027 else if (IsCRegister ||
Type->isReferenceType() ||
6028 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6031 if (!Context.isPromotableIntegerType(Type))
6033 const auto *ED = Type->getAsEnumDecl();
6036 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6038 unsigned Reason = 0;
6039 if (
Type->isReferenceType()) Reason = 1;
6040 else if (IsCRegister) Reason = 2;
6041 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6042 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6049 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6069 if (
Call->getNumArgs() < 3)
6071 diag::err_typecheck_call_too_few_args_at_least)
6072 << 0 << 3 <<
Call->getNumArgs()
6088 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6091 const QualType &ConstCharPtrTy =
6093 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6095 << Arg1->
getType() << ConstCharPtrTy << 1
6098 << 2 << Arg1->
getType() << ConstCharPtrTy;
6100 const QualType SizeTy =
Context.getSizeType();
6105 << Arg2->
getType() << SizeTy << 1
6108 << 3 << Arg2->
getType() << SizeTy;
6113bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6117 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6145 diag::err_typecheck_call_invalid_ordered_compare)
6153bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6154 unsigned BuiltinID) {
6159 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6160 BuiltinID == Builtin::BI__builtin_isinf ||
6161 BuiltinID == Builtin::BI__builtin_isinf_sign))
6165 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6166 BuiltinID == Builtin::BI__builtin_isunordered))
6170 bool IsFPClass = NumArgs == 2;
6173 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6177 for (
unsigned i = 0; i < FPArgNo; ++i) {
6178 Expr *Arg = TheCall->
getArg(i);
6191 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6199 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
6204 OrigArg = Res.
get();
6210 OrigArg = Res.
get();
6212 TheCall->
setArg(FPArgNo, OrigArg);
6214 QualType VectorResultTy;
6215 QualType ElementTy = OrigArg->
getType();
6220 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6226 diag::err_typecheck_call_invalid_unary_fp)
6238 if (!VectorResultTy.
isNull())
6239 ResultTy = VectorResultTy;
6248bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6253 for (
unsigned I = 0; I != 2; ++I) {
6254 Expr *Arg = TheCall->
getArg(I);
6264 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6279 Expr *Real = TheCall->
getArg(0);
6280 Expr *Imag = TheCall->
getArg(1);
6283 diag::err_typecheck_call_different_arg_types)
6298 diag::err_typecheck_call_too_few_args_at_least)
6299 << 0 << 2 << NumArgs
6306 unsigned NumElements = 0;
6321 unsigned NumResElements = NumArgs - 2;
6330 diag::err_vec_builtin_incompatible_vector)
6335 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6337 diag::err_vec_builtin_incompatible_vector)
6342 }
else if (NumElements != NumResElements) {
6345 ?
Context.getExtVectorType(EltType, NumResElements)
6346 :
Context.getVectorType(EltType, NumResElements,
6351 for (
unsigned I = 2; I != NumArgs; ++I) {
6359 diag::err_shufflevector_nonconstant_argument)
6365 else if (
Result->getActiveBits() > 64 ||
6366 Result->getZExtValue() >= NumElements * 2)
6368 diag::err_shufflevector_argument_too_large)
6393 diag::err_convertvector_non_vector)
6396 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6398 <<
"__builtin_convertvector");
6403 if (SrcElts != DstElts)
6405 diag::err_convertvector_incompatible_vector)
6413bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6418 diag::err_typecheck_call_too_many_args_at_most)
6419 << 0 << 3 << NumArgs << 0
6424 for (
unsigned i = 1; i != NumArgs; ++i)
6431bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6432 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6433 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6443 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6453bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6454 Expr *Arg = TheCall->
getArg(0);
6465bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6467 Expr *Arg = TheCall->
getArg(1);
6471 if (
const auto *UE =
6473 if (UE->getKind() == UETT_AlignOf ||
6474 UE->getKind() == UETT_PreferredAlignOf)
6480 if (!
Result.isPowerOf2())
6481 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6488 if (
Result > std::numeric_limits<int32_t>::max())
6496bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6501 Expr *FirstArg = TheCall->
getArg(0);
6507 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6511 TheCall->
setArg(0, FirstArgResult.
get());
6515 Expr *SecondArg = TheCall->
getArg(1);
6523 if (!
Result.isPowerOf2())
6524 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6536 Expr *ThirdArg = TheCall->
getArg(2);
6539 TheCall->
setArg(2, ThirdArg);
6545bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6546 unsigned BuiltinID =
6548 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6551 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6552 if (NumArgs < NumRequiredArgs) {
6553 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6554 << 0 << NumRequiredArgs << NumArgs
6557 if (NumArgs >= NumRequiredArgs + 0x100) {
6559 diag::err_typecheck_call_too_many_args_at_most)
6560 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6571 if (Arg.isInvalid())
6573 TheCall->
setArg(i, Arg.get());
6578 unsigned FormatIdx = i;
6588 unsigned FirstDataArg = i;
6589 while (i < NumArgs) {
6607 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6609 bool Success = CheckFormatArguments(
6612 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6636 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6645 int High,
bool RangeIsError) {
6659 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6667 PDiag(diag::warn_argument_invalid_range)
6710 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6715 if (
Value.isNegative())
6726 if ((
Value & 0xFF) != 0)
6751 Result.setIsUnsigned(
true);
6756 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6776 Result.setIsUnsigned(
true);
6784 diag::err_argument_not_shifted_byte_or_xxff)
6788bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6789 if (!Context.getTargetInfo().hasSjLjLowering())
6790 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6801 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6807bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6808 if (!Context.getTargetInfo().hasSjLjLowering())
6809 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6814bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6829 diag::err_builtin_counted_by_ref_invalid_arg)
6834 diag::err_builtin_counted_by_ref_has_side_effects)
6837 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6839 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6844 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6851 QualType MemberTy = ME->getMemberDecl()->getType();
6854 diag::err_builtin_counted_by_ref_invalid_arg)
6858 diag::err_builtin_counted_by_ref_invalid_arg)
6868bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6870 const CallExpr *CE =
6879 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6884 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6889 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6893 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6897 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6907class UncoveredArgHandler {
6908 enum {
Unknown = -1, AllCovered = -2 };
6910 signed FirstUncoveredArg =
Unknown;
6911 SmallVector<const Expr *, 4> DiagnosticExprs;
6914 UncoveredArgHandler() =
default;
6916 bool hasUncoveredArg()
const {
6917 return (FirstUncoveredArg >= 0);
6920 unsigned getUncoveredArg()
const {
6921 assert(hasUncoveredArg() &&
"no uncovered argument");
6922 return FirstUncoveredArg;
6925 void setAllCovered() {
6928 DiagnosticExprs.clear();
6929 FirstUncoveredArg = AllCovered;
6932 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6933 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6936 if (FirstUncoveredArg == AllCovered)
6941 if (NewFirstUncoveredArg == FirstUncoveredArg)
6942 DiagnosticExprs.push_back(StrExpr);
6943 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6944 DiagnosticExprs.clear();
6945 DiagnosticExprs.push_back(StrExpr);
6946 FirstUncoveredArg = NewFirstUncoveredArg;
6950 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6953enum StringLiteralCheckType {
6955 SLCT_UncheckedLiteral,
6963 bool AddendIsRight) {
6964 unsigned BitWidth = Offset.getBitWidth();
6965 unsigned AddendBitWidth = Addend.getBitWidth();
6967 if (Addend.isUnsigned()) {
6968 Addend = Addend.zext(++AddendBitWidth);
6969 Addend.setIsSigned(
true);
6972 if (AddendBitWidth > BitWidth) {
6973 Offset = Offset.sext(AddendBitWidth);
6974 BitWidth = AddendBitWidth;
6975 }
else if (BitWidth > AddendBitWidth) {
6976 Addend = Addend.sext(BitWidth);
6980 llvm::APSInt ResOffset = Offset;
6981 if (BinOpKind == BO_Add)
6982 ResOffset = Offset.sadd_ov(Addend, Ov);
6984 assert(AddendIsRight && BinOpKind == BO_Sub &&
6985 "operator must be add or sub with addend on the right");
6986 ResOffset = Offset.ssub_ov(Addend, Ov);
6992 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6993 "index (intermediate) result too big");
6994 Offset = Offset.sext(2 * BitWidth);
6995 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6999 Offset = std::move(ResOffset);
7007class FormatStringLiteral {
7008 const StringLiteral *FExpr;
7012 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7013 : FExpr(fexpr), Offset(Offset) {}
7015 const StringLiteral *getFormatString()
const {
return FExpr; }
7017 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7019 unsigned getByteLength()
const {
7020 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7023 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7030 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7031 bool isWide()
const {
return FExpr->
isWide(); }
7032 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7033 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7034 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7035 bool isPascal()
const {
return FExpr->
isPascal(); }
7037 SourceLocation getLocationOfByte(
7038 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
7039 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7040 unsigned *StartTokenByteOffset =
nullptr)
const {
7042 StartToken, StartTokenByteOffset);
7045 SourceLocation getBeginLoc() const LLVM_READONLY {
7049 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7055 Sema &S,
const FormatStringLiteral *FExpr,
7060 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7061 bool IgnoreStringsWithoutSpecifiers);
7070static StringLiteralCheckType
7076 llvm::SmallBitVector &CheckedVarArgs,
7077 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7078 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7079 bool IgnoreStringsWithoutSpecifiers =
false) {
7081 return SLCT_NotALiteral;
7083 assert(Offset.isSigned() &&
"invalid offset");
7086 return SLCT_NotALiteral;
7095 return SLCT_UncheckedLiteral;
7098 case Stmt::InitListExprClass:
7102 format_idx, firstDataArg,
Type, CallType,
7103 false, CheckedVarArgs,
7104 UncoveredArg, Offset, CallerFormatParamIdx,
7105 IgnoreStringsWithoutSpecifiers);
7107 return SLCT_NotALiteral;
7108 case Stmt::BinaryConditionalOperatorClass:
7109 case Stmt::ConditionalOperatorClass: {
7118 bool CheckLeft =
true, CheckRight =
true;
7121 if (
C->getCond()->EvaluateAsBooleanCondition(
7133 StringLiteralCheckType Left;
7135 Left = SLCT_UncheckedLiteral;
7138 Args, APK, format_idx, firstDataArg,
Type,
7139 CallType, InFunctionCall, CheckedVarArgs,
7140 UncoveredArg, Offset, CallerFormatParamIdx,
7141 IgnoreStringsWithoutSpecifiers);
7142 if (Left == SLCT_NotALiteral || !CheckRight) {
7148 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7149 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7150 UncoveredArg, Offset, CallerFormatParamIdx,
7151 IgnoreStringsWithoutSpecifiers);
7153 return (CheckLeft && Left < Right) ? Left : Right;
7156 case Stmt::ImplicitCastExprClass:
7160 case Stmt::OpaqueValueExprClass:
7165 return SLCT_NotALiteral;
7167 case Stmt::PredefinedExprClass:
7171 return SLCT_UncheckedLiteral;
7173 case Stmt::DeclRefExprClass: {
7179 bool isConstant =
false;
7183 isConstant = AT->getElementType().isConstant(S.
Context);
7185 isConstant = T.isConstant(S.
Context) &&
7186 PT->getPointeeType().isConstant(S.
Context);
7187 }
else if (T->isObjCObjectPointerType()) {
7190 isConstant = T.isConstant(S.
Context);
7194 if (
const Expr *
Init = VD->getAnyInitializer()) {
7197 if (InitList->isStringLiteralInit())
7198 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7201 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7202 firstDataArg,
Type, CallType,
false,
7203 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7254 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7255 if (CallerFormatParamIdx)
7256 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7257 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7258 for (
const auto *PVFormatMatches :
7259 D->specific_attrs<FormatMatchesAttr>()) {
7264 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7268 S.
Diag(Args[format_idx]->getBeginLoc(),
7269 diag::warn_format_string_type_incompatible)
7270 << PVFormatMatches->getType()->getName()
7272 if (!InFunctionCall) {
7273 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7274 diag::note_format_string_defined);
7276 return SLCT_UncheckedLiteral;
7279 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7280 Args, APK, format_idx, firstDataArg,
Type, CallType,
7281 false, CheckedVarArgs, UncoveredArg,
7282 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7286 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7289 PVFormat->getFirstArg(), &CallerFSI))
7291 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7295 S.
Diag(Args[format_idx]->getBeginLoc(),
7296 diag::warn_format_string_type_incompatible)
7297 << PVFormat->getType()->getName()
7299 if (!InFunctionCall) {
7302 return SLCT_UncheckedLiteral;
7315 return SLCT_UncheckedLiteral;
7323 return SLCT_NotALiteral;
7326 case Stmt::CallExprClass:
7327 case Stmt::CXXMemberCallExprClass: {
7331 StringLiteralCheckType CommonResult;
7332 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7333 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7335 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7336 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7337 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7344 return CommonResult;
7346 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7348 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7349 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7352 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7353 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7354 UncoveredArg, Offset, CallerFormatParamIdx,
7355 IgnoreStringsWithoutSpecifiers);
7361 format_idx, firstDataArg,
Type, CallType,
7362 false, CheckedVarArgs,
7363 UncoveredArg, Offset, CallerFormatParamIdx,
7364 IgnoreStringsWithoutSpecifiers);
7365 return SLCT_NotALiteral;
7367 case Stmt::ObjCMessageExprClass: {
7369 if (
const auto *MD = ME->getMethodDecl()) {
7370 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7379 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7381 MD->getSelector().isKeywordSelector(
7382 {
"localizedStringForKey",
"value",
"table"})) {
7383 IgnoreStringsWithoutSpecifiers =
true;
7386 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7388 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7389 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7390 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7394 return SLCT_NotALiteral;
7396 case Stmt::ObjCStringLiteralClass:
7397 case Stmt::StringLiteralClass: {
7406 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7409 return SLCT_NotALiteral;
7411 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7413 format_idx, firstDataArg,
Type, InFunctionCall,
7414 CallType, CheckedVarArgs, UncoveredArg,
7415 IgnoreStringsWithoutSpecifiers);
7416 return SLCT_CheckedLiteral;
7419 return SLCT_NotALiteral;
7421 case Stmt::BinaryOperatorClass: {
7435 if (LIsInt != RIsInt) {
7439 if (BinOpKind == BO_Add) {
7452 return SLCT_NotALiteral;
7454 case Stmt::UnaryOperatorClass: {
7456 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7457 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7459 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7469 return SLCT_NotALiteral;
7473 return SLCT_NotALiteral;
7484 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7485 if (isa_and_nonnull<StringLiteral>(LVE))
7506 return "freebsd_kprintf";
7515 return llvm::StringSwitch<FormatStringType>(Flavor)
7517 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7522 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7538bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7542 llvm::SmallBitVector &CheckedVarArgs) {
7543 FormatStringInfo FSI;
7547 return CheckFormatArguments(
7548 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7553bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7557 llvm::SmallBitVector &CheckedVarArgs) {
7558 FormatStringInfo FSI;
7562 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7563 Format->getFormatString(), FSI.FormatIdx,
7565 CallType, Loc, Range, CheckedVarArgs);
7573 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7586 unsigned CallerArgumentIndexOffset =
7589 unsigned FirstArgumentIndex = -1;
7599 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7600 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7604 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7605 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7607 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7610 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7611 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7614 FirstArgumentIndex =
7615 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7621 ? (NumCallerParams + CallerArgumentIndexOffset)
7626 if (!ReferenceFormatString)
7632 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7634 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7636 std::string
Attr, Fixit;
7637 llvm::raw_string_ostream AttrOS(
Attr);
7639 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7640 << FirstArgumentIndex <<
")";
7642 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7644 AttrOS.write_escaped(ReferenceFormatString->
getString());
7648 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7659 llvm::raw_string_ostream IS(Fixit);
7667 if (LO.C23 || LO.CPlusPlus11)
7668 IS <<
"[[gnu::" <<
Attr <<
"]]";
7669 else if (LO.ObjC || LO.GNUMode)
7670 IS <<
"__attribute__((" <<
Attr <<
"))";
7684 Caller->
addAttr(FormatAttr::CreateImplicit(
7686 FormatStringIndex, FirstArgumentIndex));
7688 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7690 FormatStringIndex, ReferenceFormatString));
7694 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7706 unsigned format_idx,
unsigned firstDataArg,
7710 llvm::SmallBitVector &CheckedVarArgs) {
7712 if (format_idx >= Args.size()) {
7713 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7717 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7731 UncoveredArgHandler UncoveredArg;
7732 std::optional<unsigned> CallerParamIdx;
7734 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7735 firstDataArg,
Type, CallType,
7736 true, CheckedVarArgs, UncoveredArg,
7737 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7740 if (UncoveredArg.hasUncoveredArg()) {
7741 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7742 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7743 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7746 if (CT != SLCT_NotALiteral)
7748 return CT == SLCT_CheckedLiteral;
7754 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7760 this, Args, APK, ReferenceFormatString, format_idx,
7761 firstDataArg,
Type, *CallerParamIdx, Loc))
7771 if (Args.size() == firstDataArg) {
7772 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7780 Diag(FormatLoc, diag::note_format_security_fixit)
7784 Diag(FormatLoc, diag::note_format_security_fixit)
7789 Diag(FormatLoc, diag::warn_format_nonliteral)
7800 const FormatStringLiteral *FExpr;
7801 const Expr *OrigFormatExpr;
7803 const unsigned FirstDataArg;
7804 const unsigned NumDataArgs;
7807 ArrayRef<const Expr *> Args;
7809 llvm::SmallBitVector CoveredArgs;
7810 bool usesPositionalArgs =
false;
7811 bool atFirstArg =
true;
7812 bool inFunctionCall;
7814 llvm::SmallBitVector &CheckedVarArgs;
7815 UncoveredArgHandler &UncoveredArg;
7818 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7820 unsigned firstDataArg,
unsigned numDataArgs,
7822 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7824 llvm::SmallBitVector &CheckedVarArgs,
7825 UncoveredArgHandler &UncoveredArg)
7826 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7827 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7828 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7829 inFunctionCall(inFunctionCall), CallType(callType),
7830 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7831 CoveredArgs.resize(numDataArgs);
7832 CoveredArgs.reset();
7835 bool HasFormatArguments()
const {
7840 void DoneProcessing();
7842 void HandleIncompleteSpecifier(
const char *startSpecifier,
7843 unsigned specifierLen)
override;
7845 void HandleInvalidLengthModifier(
7846 const analyze_format_string::FormatSpecifier &FS,
7847 const analyze_format_string::ConversionSpecifier &CS,
7848 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
7850 void HandleNonStandardLengthModifier(
7851 const analyze_format_string::FormatSpecifier &FS,
7852 const char *startSpecifier,
unsigned specifierLen);
7854 void HandleNonStandardConversionSpecifier(
7855 const analyze_format_string::ConversionSpecifier &CS,
7856 const char *startSpecifier,
unsigned specifierLen);
7858 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7860 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
7863 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7865 void HandleNullChar(
const char *nullCharacter)
override;
7867 template <
typename Range>
7869 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7870 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7871 bool IsStringLocation, Range StringRange,
7872 ArrayRef<FixItHint> Fixit = {});
7875 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7876 const char *startSpec,
7877 unsigned specifierLen,
7878 const char *csStart,
unsigned csLen);
7880 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7881 const char *startSpec,
7882 unsigned specifierLen);
7884 SourceRange getFormatStringRange();
7885 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7886 unsigned specifierLen);
7887 SourceLocation getLocationOfByte(
const char *x);
7889 const Expr *getDataArg(
unsigned i)
const;
7891 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7892 const analyze_format_string::ConversionSpecifier &CS,
7893 const char *startSpecifier,
unsigned specifierLen,
7896 template <
typename Range>
7897 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7898 bool IsStringLocation, Range StringRange,
7899 ArrayRef<FixItHint> Fixit = {});
7904SourceRange CheckFormatHandler::getFormatStringRange() {
7909CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
7910 unsigned specifierLen) {
7912 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7920SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7925void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7926 unsigned specifierLen) {
7927 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7928 getLocationOfByte(startSpecifier),
7930 getSpecifierRange(startSpecifier, specifierLen));
7933void CheckFormatHandler::HandleInvalidLengthModifier(
7936 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7948 getSpecifierRange(startSpecifier, specifierLen));
7950 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7951 << FixedLM->toString()
7956 if (DiagID == diag::warn_format_nonsensical_length)
7962 getSpecifierRange(startSpecifier, specifierLen), Hint);
7966void CheckFormatHandler::HandleNonStandardLengthModifier(
7968 const char *startSpecifier,
unsigned specifierLen) {
7977 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7981 getSpecifierRange(startSpecifier, specifierLen));
7983 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7984 << FixedLM->toString()
7988 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7992 getSpecifierRange(startSpecifier, specifierLen));
7996void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7998 const char *startSpecifier,
unsigned specifierLen) {
8004 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8008 getSpecifierRange(startSpecifier, specifierLen));
8011 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8012 << FixedCS->toString()
8015 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8019 getSpecifierRange(startSpecifier, specifierLen));
8023void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8025 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8026 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8027 getLocationOfByte(startPos),
8029 getSpecifierRange(startPos, posLen));
8032void CheckFormatHandler::HandleInvalidPosition(
8033 const char *startSpecifier,
unsigned specifierLen,
8036 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8037 EmitFormatDiagnostic(
8038 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8039 getLocationOfByte(startSpecifier),
true,
8040 getSpecifierRange(startSpecifier, specifierLen));
8043void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8047 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8048 getLocationOfByte(startPos),
8050 getSpecifierRange(startPos, posLen));
8053void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8056 EmitFormatDiagnostic(
8057 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8058 getLocationOfByte(nullCharacter),
true,
8059 getFormatStringRange());
8065const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8066 return Args[FirstDataArg + i];
8069void CheckFormatHandler::DoneProcessing() {
8072 if (HasFormatArguments()) {
8075 signed notCoveredArg = CoveredArgs.find_first();
8076 if (notCoveredArg >= 0) {
8077 assert((
unsigned)notCoveredArg < NumDataArgs);
8078 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8080 UncoveredArg.setAllCovered();
8085void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8086 const Expr *ArgExpr) {
8087 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8098 for (
auto E : DiagnosticExprs)
8101 CheckFormatHandler::EmitFormatDiagnostic(
8102 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8106bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8108 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8109 bool keepGoing =
true;
8110 if (argIndex < NumDataArgs) {
8113 CoveredArgs.set(argIndex);
8128 std::string CodePointStr;
8129 if (!llvm::sys::locale::isPrint(*csStart)) {
8130 llvm::UTF32 CodePoint;
8131 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8132 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8133 llvm::ConversionResult
Result =
8134 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8136 if (
Result != llvm::conversionOK) {
8137 unsigned char FirstChar = *csStart;
8138 CodePoint = (llvm::UTF32)FirstChar;
8141 llvm::raw_string_ostream
OS(CodePointStr);
8142 if (CodePoint < 256)
8143 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8144 else if (CodePoint <= 0xFFFF)
8145 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8147 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8151 EmitFormatDiagnostic(
8152 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8153 true, getSpecifierRange(startSpec, specifierLen));
8158void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8159 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8160 EmitFormatDiagnostic(
8161 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8162 true, getSpecifierRange(startSpec, specifierLen));
8165bool CheckFormatHandler::CheckNumArgs(
8168 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8170 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8173 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8174 << (argIndex + 1) << NumDataArgs)
8175 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8176 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8178 getSpecifierRange(startSpecifier, specifierLen));
8182 UncoveredArg.setAllCovered();
8188template <
typename Range>
8191 bool IsStringLocation,
8194 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8195 IsStringLocation, StringRange, FixIt);
8225template <
typename Range>
8226void CheckFormatHandler::EmitFormatDiagnostic(
8227 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8230 if (InFunctionCall) {
8235 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8239 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8240 diag::note_format_string_defined);
8242 Note << StringRange;
8251class CheckPrintfHandler :
public CheckFormatHandler {
8253 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8255 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8257 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8259 llvm::SmallBitVector &CheckedVarArgs,
8260 UncoveredArgHandler &UncoveredArg)
8261 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8262 numDataArgs, beg, APK, Args, formatIdx,
8263 inFunctionCall, CallType, CheckedVarArgs,
8266 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8269 bool allowsObjCArg()
const {
8270 return FSType == FormatStringType::NSString ||
8271 FSType == FormatStringType::OSLog ||
8272 FSType == FormatStringType::OSTrace;
8275 bool HandleInvalidPrintfConversionSpecifier(
8276 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8277 unsigned specifierLen)
override;
8279 void handleInvalidMaskType(StringRef MaskType)
override;
8281 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8282 const char *startSpecifier,
unsigned specifierLen,
8283 const TargetInfo &
Target)
override;
8284 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8285 const char *StartSpecifier,
unsigned SpecifierLen,
8288 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8289 unsigned k,
const char *startSpecifier,
8290 unsigned specifierLen);
8291 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8292 const analyze_printf::OptionalAmount &Amt,
8293 unsigned type,
const char *startSpecifier,
8294 unsigned specifierLen);
8295 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8296 const analyze_printf::OptionalFlag &flag,
8297 const char *startSpecifier,
unsigned specifierLen);
8298 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8299 const analyze_printf::OptionalFlag &ignoredFlag,
8300 const analyze_printf::OptionalFlag &flag,
8301 const char *startSpecifier,
unsigned specifierLen);
8302 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8304 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8305 unsigned flagLen)
override;
8307 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8308 unsigned flagLen)
override;
8311 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8312 const char *flagsEnd,
8313 const char *conversionPosition)
override;
8318class EquatableFormatArgument {
8320 enum SpecifierSensitivity :
unsigned {
8327 enum FormatArgumentRole :
unsigned {
8335 analyze_format_string::ArgType ArgType;
8337 StringRef SpecifierLetter;
8338 CharSourceRange
Range;
8339 SourceLocation ElementLoc;
8340 FormatArgumentRole
Role : 2;
8341 SpecifierSensitivity Sensitivity : 2;
8342 unsigned Position : 14;
8343 unsigned ModifierFor : 14;
8345 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8346 bool InFunctionCall)
const;
8349 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8351 StringRef SpecifierLetter,
8352 analyze_format_string::ArgType ArgType,
8353 FormatArgumentRole
Role,
8354 SpecifierSensitivity Sensitivity,
unsigned Position,
8355 unsigned ModifierFor)
8356 : ArgType(ArgType), LengthMod(LengthMod),
8357 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8358 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8359 ModifierFor(ModifierFor) {}
8361 unsigned getPosition()
const {
return Position; }
8362 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8364 analyze_format_string::LengthModifier getLengthModifier()
const {
8365 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
8367 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8369 std::string buildFormatSpecifier()
const {
8371 llvm::raw_string_ostream(result)
8372 << getLengthModifier().toString() << SpecifierLetter;
8376 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8377 const Expr *FmtExpr,
bool InFunctionCall)
const;
8381class DecomposePrintfHandler :
public CheckPrintfHandler {
8382 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8385 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8386 const Expr *origFormatExpr,
8388 unsigned numDataArgs,
bool isObjC,
const char *beg,
8390 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8392 llvm::SmallBitVector &CheckedVarArgs,
8393 UncoveredArgHandler &UncoveredArg,
8394 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8395 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8396 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8397 inFunctionCall, CallType, CheckedVarArgs,
8399 Specs(Specs), HadError(
false) {}
8403 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8405 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8407 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8408 const char *startSpecifier,
8409 unsigned specifierLen,
8410 const TargetInfo &
Target)
override;
8415bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8417 unsigned specifierLen) {
8421 return HandleInvalidConversionSpecifier(
8426void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8427 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8435 return T->isRecordType() || T->isComplexType();
8438bool CheckPrintfHandler::HandleAmount(
8440 const char *startSpecifier,
unsigned specifierLen) {
8442 if (HasFormatArguments()) {
8444 if (argIndex >= NumDataArgs) {
8445 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8449 getSpecifierRange(startSpecifier, specifierLen));
8459 CoveredArgs.set(argIndex);
8460 const Expr *Arg = getDataArg(argIndex);
8471 ? diag::err_printf_asterisk_wrong_type
8472 : diag::warn_printf_asterisk_wrong_type;
8473 EmitFormatDiagnostic(S.
PDiag(DiagID)
8478 getSpecifierRange(startSpecifier, specifierLen));
8488void CheckPrintfHandler::HandleInvalidAmount(
8491 const char *startSpecifier,
unsigned specifierLen) {
8501 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8505 getSpecifierRange(startSpecifier, specifierLen), fixit);
8510 const char *startSpecifier,
8511 unsigned specifierLen) {
8515 EmitFormatDiagnostic(
8516 S.
PDiag(diag::warn_printf_nonsensical_flag)
8520 getSpecifierRange(startSpecifier, specifierLen),
8524void CheckPrintfHandler::HandleIgnoredFlag(
8528 unsigned specifierLen) {
8530 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8534 getSpecifierRange(startSpecifier, specifierLen),
8536 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8539void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8542 EmitFormatDiagnostic(
8543 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8544 true, getSpecifierRange(startFlag, flagLen));
8547void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8550 auto Range = getSpecifierRange(startFlag, flagLen);
8551 StringRef flag(startFlag, flagLen);
8552 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8553 getLocationOfByte(startFlag),
8558void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8559 const char *flagsStart,
const char *flagsEnd,
8560 const char *conversionPosition) {
8562 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8563 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8564 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8565 getLocationOfByte(conversionPosition),
8571 const Expr *FmtExpr,
8572 bool InFunctionCall)
const {
8573 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8574 ElementLoc,
true, Range);
8577bool EquatableFormatArgument::VerifyCompatible(
8578 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8579 bool InFunctionCall)
const {
8584 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8585 FmtExpr, InFunctionCall);
8586 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8590 if (
Role != FAR_Data) {
8591 if (ModifierFor !=
Other.ModifierFor) {
8594 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8595 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8596 FmtExpr, InFunctionCall);
8597 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8603 bool HadError =
false;
8604 if (Sensitivity !=
Other.Sensitivity) {
8607 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8608 << Sensitivity <<
Other.Sensitivity,
8609 FmtExpr, InFunctionCall);
8610 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8611 << 0 <<
Other.Range;
8614 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8618 case MK::MatchPromotion:
8622 case MK::NoMatchTypeConfusion:
8623 case MK::NoMatchPromotionTypeConfusion:
8625 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8626 << buildFormatSpecifier()
8627 <<
Other.buildFormatSpecifier(),
8628 FmtExpr, InFunctionCall);
8629 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8630 << 0 <<
Other.Range;
8633 case MK::NoMatchPedantic:
8635 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8636 << buildFormatSpecifier()
8637 <<
Other.buildFormatSpecifier(),
8638 FmtExpr, InFunctionCall);
8639 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8640 << 0 <<
Other.Range;
8643 case MK::NoMatchSignedness:
8645 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8646 << buildFormatSpecifier()
8647 <<
Other.buildFormatSpecifier(),
8648 FmtExpr, InFunctionCall);
8649 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8650 << 0 <<
Other.Range;
8656bool DecomposePrintfHandler::GetSpecifiers(
8657 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8660 StringRef
Data = FSL->getString();
8661 const char *Str =
Data.data();
8662 llvm::SmallBitVector BV;
8663 UncoveredArgHandler UA;
8664 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8665 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8677 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8678 const EquatableFormatArgument &B) {
8679 return A.getPosition() < B.getPosition();
8684bool DecomposePrintfHandler::HandlePrintfSpecifier(
8687 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8702 const unsigned Unset = ~0;
8703 unsigned FieldWidthIndex = Unset;
8704 unsigned PrecisionIndex = Unset;
8708 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8709 FieldWidthIndex = Specs.size();
8711 getSpecifierRange(startSpecifier, specifierLen),
8712 getLocationOfByte(FieldWidth.getStart()),
8714 FieldWidth.getArgType(S.
Context),
8715 EquatableFormatArgument::FAR_FieldWidth,
8716 EquatableFormatArgument::SS_None,
8717 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
8723 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8724 PrecisionIndex = Specs.size();
8726 getSpecifierRange(startSpecifier, specifierLen),
8727 getLocationOfByte(Precision.getStart()),
8729 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8730 EquatableFormatArgument::SS_None,
8731 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8737 unsigned SpecIndex =
8739 if (FieldWidthIndex != Unset)
8740 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8741 if (PrecisionIndex != Unset)
8742 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8744 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8746 Sensitivity = EquatableFormatArgument::SS_Private;
8748 Sensitivity = EquatableFormatArgument::SS_Public;
8750 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8752 Sensitivity = EquatableFormatArgument::SS_None;
8755 getSpecifierRange(startSpecifier, specifierLen),
8758 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8763 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8768 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8769 SpecIndex + 1, SpecIndex);
8777template<
typename MemberKind>
8788 R.suppressDiagnostics();
8795 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8810 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8812 if ((*MI)->getMinRequiredArguments() == 0)
8820bool CheckPrintfHandler::checkForCStrMembers(
8827 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8830 if (
Method->getMinRequiredArguments() == 0 &&
8843bool CheckPrintfHandler::HandlePrintfSpecifier(
8856 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8857 startSpecifier, specifierLen);
8869 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
8874 if (!CS.consumesDataArgument()) {
8882 if (argIndex < NumDataArgs) {
8886 CoveredArgs.set(argIndex);
8893 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8896 if (HasFormatArguments()) {
8898 CoveredArgs.set(argIndex + 1);
8901 const Expr *Ex = getDataArg(argIndex);
8905 : ArgType::CPointerTy;
8907 EmitFormatDiagnostic(
8908 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8912 getSpecifierRange(startSpecifier, specifierLen));
8915 Ex = getDataArg(argIndex + 1);
8918 EmitFormatDiagnostic(
8919 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8923 getSpecifierRange(startSpecifier, specifierLen));
8930 if (!allowsObjCArg() && CS.isObjCArg()) {
8931 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8938 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8945 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8946 getLocationOfByte(CS.getStart()),
8948 getSpecifierRange(startSpecifier, specifierLen));
8958 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8965 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8969 getSpecifierRange(startSpecifier, specifierLen));
8972 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8976 getSpecifierRange(startSpecifier, specifierLen));
8980 const llvm::Triple &Triple =
Target.getTriple();
8982 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8983 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8984 getLocationOfByte(CS.getStart()),
8986 getSpecifierRange(startSpecifier, specifierLen));
8992 startSpecifier, specifierLen);
8998 startSpecifier, specifierLen);
9004 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9005 getLocationOfByte(startSpecifier),
9007 getSpecifierRange(startSpecifier, specifierLen));
9016 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9018 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9027 startSpecifier, specifierLen);
9030 startSpecifier, specifierLen);
9035 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9036 diag::warn_format_nonsensical_length);
9038 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9040 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9041 diag::warn_format_non_standard_conversion_spec);
9044 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9047 if (!HasFormatArguments())
9050 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9053 const Expr *Arg = getDataArg(argIndex);
9057 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9069 case Stmt::ArraySubscriptExprClass:
9070 case Stmt::CallExprClass:
9071 case Stmt::CharacterLiteralClass:
9072 case Stmt::CXXBoolLiteralExprClass:
9073 case Stmt::DeclRefExprClass:
9074 case Stmt::FloatingLiteralClass:
9075 case Stmt::IntegerLiteralClass:
9076 case Stmt::MemberExprClass:
9077 case Stmt::ObjCArrayLiteralClass:
9078 case Stmt::ObjCBoolLiteralExprClass:
9079 case Stmt::ObjCBoxedExprClass:
9080 case Stmt::ObjCDictionaryLiteralClass:
9081 case Stmt::ObjCEncodeExprClass:
9082 case Stmt::ObjCIvarRefExprClass:
9083 case Stmt::ObjCMessageExprClass:
9084 case Stmt::ObjCPropertyRefExprClass:
9085 case Stmt::ObjCStringLiteralClass:
9086 case Stmt::ObjCSubscriptRefExprClass:
9087 case Stmt::ParenExprClass:
9088 case Stmt::StringLiteralClass:
9089 case Stmt::UnaryOperatorClass:
9096static std::pair<QualType, StringRef>
9102 StringRef Name = UserTy->getDecl()->getName();
9103 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9104 .Case(
"CFIndex", Context.getNSIntegerType())
9105 .Case(
"NSInteger", Context.getNSIntegerType())
9106 .Case(
"NSUInteger", Context.getNSUIntegerType())
9107 .Case(
"SInt32", Context.IntTy)
9108 .Case(
"UInt32", Context.UnsignedIntTy)
9112 return std::make_pair(CastTy, Name);
9114 TyTy = UserTy->desugar();
9118 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9128 StringRef TrueName, FalseName;
9131 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9133 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9135 if (TrueTy == FalseTy)
9136 return std::make_pair(TrueTy, TrueName);
9137 else if (TrueTy.
isNull())
9138 return std::make_pair(FalseTy, FalseName);
9139 else if (FalseTy.
isNull())
9140 return std::make_pair(TrueTy, TrueName);
9143 return std::make_pair(
QualType(), StringRef());
9162 From = VecTy->getElementType();
9164 To = VecTy->getElementType();
9175 diag::warn_format_conversion_argument_type_mismatch_signedness,
9179 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9186bool CheckPrintfHandler::checkFormatExpr(
9188 unsigned SpecifierLen,
const Expr *E) {
9199 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9200 ExprTy = TET->getUnderlyingExpr()->getType();
9203 if (
const OverflowBehaviorType *OBT =
9205 ExprTy = OBT->getUnderlyingType();
9219 getSpecifierRange(StartSpecifier, SpecifierLen);
9221 llvm::raw_svector_ostream os(FSString);
9223 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9234 getSpecifierRange(StartSpecifier, SpecifierLen);
9235 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9245 if (
Match == ArgType::Match)
9249 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9258 E = ICE->getSubExpr();
9268 if (OrigMatch == ArgType::NoMatchSignedness &&
9269 ImplicitMatch != ArgType::NoMatchSignedness)
9276 if (ImplicitMatch == ArgType::Match)
9294 if (
Match == ArgType::MatchPromotion)
9298 if (
Match == ArgType::MatchPromotion) {
9302 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9303 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9307 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9308 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9309 Match = ImplicitMatch;
9310 assert(
Match != ArgType::MatchPromotion);
9313 bool IsEnum =
false;
9314 bool IsScopedEnum =
false;
9317 IntendedTy = ED->getIntegerType();
9318 if (!ED->isScoped()) {
9319 ExprTy = IntendedTy;
9324 IsScopedEnum =
true;
9331 if (isObjCContext() &&
9342 const llvm::APInt &
V = IL->getValue();
9352 if (TD->getUnderlyingType() == IntendedTy)
9362 bool ShouldNotPrintDirectly =
false;
9363 StringRef CastTyName;
9366 std::tie(CastTy, CastTyName) =
9372 if (!IsScopedEnum &&
9373 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9377 IntendedTy = CastTy;
9378 ShouldNotPrintDirectly =
true;
9383 PrintfSpecifier fixedFS = FS;
9390 llvm::raw_svector_ostream os(buf);
9393 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9395 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9401 llvm_unreachable(
"expected non-matching");
9403 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9406 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9409 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9412 Diag = diag::warn_format_conversion_argument_type_mismatch;
9433 llvm::raw_svector_ostream CastFix(CastBuf);
9434 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9436 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9442 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9447 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9469 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9475 Name = TypedefTy->getDecl()->getName();
9479 ? diag::warn_format_argument_needs_cast_pedantic
9480 : diag::warn_format_argument_needs_cast;
9481 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9492 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9493 : diag::warn_format_conversion_argument_type_mismatch;
9495 EmitFormatDiagnostic(
9503 getSpecifierRange(StartSpecifier, SpecifierLen);
9507 bool EmitTypeMismatch =
false;
9516 llvm_unreachable(
"expected non-matching");
9518 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9521 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9524 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9528 ? diag::err_format_conversion_argument_type_mismatch
9529 : diag::warn_format_conversion_argument_type_mismatch;
9533 EmitFormatDiagnostic(
9542 EmitTypeMismatch =
true;
9544 EmitFormatDiagnostic(
9545 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9546 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9550 checkForCStrMembers(AT, E);
9556 EmitTypeMismatch =
true;
9558 EmitFormatDiagnostic(
9559 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9560 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9573 if (EmitTypeMismatch) {
9579 EmitFormatDiagnostic(
9580 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9586 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9587 "format string specifier index out of range");
9588 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9598class CheckScanfHandler :
public CheckFormatHandler {
9600 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9602 unsigned firstDataArg,
unsigned numDataArgs,
9604 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9606 llvm::SmallBitVector &CheckedVarArgs,
9607 UncoveredArgHandler &UncoveredArg)
9608 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9609 numDataArgs, beg, APK, Args, formatIdx,
9610 inFunctionCall, CallType, CheckedVarArgs,
9613 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9614 const char *startSpecifier,
9615 unsigned specifierLen)
override;
9618 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9619 const char *startSpecifier,
9620 unsigned specifierLen)
override;
9622 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9627void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9629 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9630 getLocationOfByte(end),
true,
9631 getSpecifierRange(start, end - start));
9634bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9636 unsigned specifierLen) {
9640 return HandleInvalidConversionSpecifier(
9645bool CheckScanfHandler::HandleScanfSpecifier(
9647 unsigned specifierLen) {
9660 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9661 startSpecifier, specifierLen);
9672 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9687 if (argIndex < NumDataArgs) {
9691 CoveredArgs.set(argIndex);
9697 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9698 diag::warn_format_nonsensical_length);
9700 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9702 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9703 diag::warn_format_non_standard_conversion_spec);
9706 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9709 if (!HasFormatArguments())
9712 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9716 const Expr *Ex = getDataArg(argIndex);
9734 ScanfSpecifier fixedFS = FS;
9739 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9741 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9742 : diag::warn_format_conversion_argument_type_mismatch;
9747 llvm::raw_svector_ostream os(buf);
9750 EmitFormatDiagnostic(
9755 getSpecifierRange(startSpecifier, specifierLen),
9757 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9764 getSpecifierRange(startSpecifier, specifierLen));
9774 const Expr *FmtExpr,
bool InFunctionCall) {
9775 bool HadError =
false;
9776 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9777 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9778 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9790 for (; FmtIter < FmtEnd; ++FmtIter) {
9794 if (FmtIter->getPosition() < RefIter->getPosition())
9798 if (FmtIter->getPosition() > RefIter->getPosition())
9802 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9806 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9807 return Arg.getPosition() != RefIter->getPosition();
9811 if (FmtIter < FmtEnd) {
9812 CheckFormatHandler::EmitFormatDiagnostic(
9813 S, InFunctionCall, FmtExpr,
9814 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9815 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9816 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9817 }
else if (RefIter < RefEnd) {
9818 CheckFormatHandler::EmitFormatDiagnostic(
9819 S, InFunctionCall, FmtExpr,
9820 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9823 << 1 << RefIter->getSourceRange();
9829 Sema &S,
const FormatStringLiteral *FExpr,
9834 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9835 bool IgnoreStringsWithoutSpecifiers) {
9837 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9838 CheckFormatHandler::EmitFormatDiagnostic(
9839 S, inFunctionCall, Args[format_idx],
9840 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9846 StringRef StrRef = FExpr->getString();
9847 const char *Str = StrRef.data();
9851 assert(T &&
"String literal not of constant array type!");
9852 size_t TypeSize = T->getZExtSize();
9853 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9854 const unsigned numDataArgs = Args.size() - firstDataArg;
9856 if (IgnoreStringsWithoutSpecifiers &&
9863 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9864 CheckFormatHandler::EmitFormatDiagnostic(
9865 S, inFunctionCall, Args[format_idx],
9866 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9867 FExpr->getBeginLoc(),
9873 if (StrLen == 0 && numDataArgs > 0) {
9874 CheckFormatHandler::EmitFormatDiagnostic(
9875 S, inFunctionCall, Args[format_idx],
9876 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9887 if (ReferenceFormatString ==
nullptr) {
9888 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9889 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9890 inFunctionCall, CallType, CheckedVarArgs,
9900 Type, ReferenceFormatString, FExpr->getFormatString(),
9901 inFunctionCall ?
nullptr : Args[format_idx]);
9904 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9905 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9906 CallType, CheckedVarArgs, UncoveredArg);
9926 FormatStringLiteral RefLit = AuthoritativeFormatString;
9927 FormatStringLiteral TestLit = TestedFormatString;
9929 bool DiagAtStringLiteral;
9930 if (FunctionCallArg) {
9931 Arg = FunctionCallArg;
9932 DiagAtStringLiteral =
false;
9934 Arg = TestedFormatString;
9935 DiagAtStringLiteral =
true;
9937 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9938 AuthoritativeFormatString,
Type,
9939 IsObjC,
true, RefArgs) &&
9940 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9941 DiagAtStringLiteral, FmtArgs)) {
9943 TestedFormatString, FmtArgs, Arg,
9944 DiagAtStringLiteral);
9957 FormatStringLiteral RefLit = Str;
9961 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9970 bool HadError =
false;
9971 auto Iter = Args.begin();
9972 auto End = Args.end();
9973 while (Iter != End) {
9974 const auto &FirstInGroup = *Iter;
9976 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9978 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9987 const char *Str = StrRef.data();
9990 assert(T &&
"String literal not of constant array type!");
9991 size_t TypeSize = T->getZExtSize();
9992 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10002 switch (AbsFunction) {
10006 case Builtin::BI__builtin_abs:
10007 return Builtin::BI__builtin_labs;
10008 case Builtin::BI__builtin_labs:
10009 return Builtin::BI__builtin_llabs;
10010 case Builtin::BI__builtin_llabs:
10013 case Builtin::BI__builtin_fabsf:
10014 return Builtin::BI__builtin_fabs;
10015 case Builtin::BI__builtin_fabs:
10016 return Builtin::BI__builtin_fabsl;
10017 case Builtin::BI__builtin_fabsl:
10020 case Builtin::BI__builtin_cabsf:
10021 return Builtin::BI__builtin_cabs;
10022 case Builtin::BI__builtin_cabs:
10023 return Builtin::BI__builtin_cabsl;
10024 case Builtin::BI__builtin_cabsl:
10027 case Builtin::BIabs:
10028 return Builtin::BIlabs;
10029 case Builtin::BIlabs:
10030 return Builtin::BIllabs;
10031 case Builtin::BIllabs:
10034 case Builtin::BIfabsf:
10035 return Builtin::BIfabs;
10036 case Builtin::BIfabs:
10037 return Builtin::BIfabsl;
10038 case Builtin::BIfabsl:
10041 case Builtin::BIcabsf:
10042 return Builtin::BIcabs;
10043 case Builtin::BIcabs:
10044 return Builtin::BIcabsl;
10045 case Builtin::BIcabsl:
10052 unsigned AbsType) {
10074 unsigned AbsFunctionKind) {
10075 unsigned BestKind = 0;
10076 uint64_t ArgSize = Context.getTypeSize(ArgType);
10077 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10080 if (Context.getTypeSize(ParamType) >= ArgSize) {
10083 else if (Context.hasSameType(ParamType, ArgType)) {
10099 if (T->isIntegralOrEnumerationType())
10101 if (T->isRealFloatingType())
10103 if (T->isAnyComplexType())
10106 llvm_unreachable(
"Type not integer, floating, or complex");
10113 switch (ValueKind) {
10118 case Builtin::BI__builtin_fabsf:
10119 case Builtin::BI__builtin_fabs:
10120 case Builtin::BI__builtin_fabsl:
10121 case Builtin::BI__builtin_cabsf:
10122 case Builtin::BI__builtin_cabs:
10123 case Builtin::BI__builtin_cabsl:
10124 return Builtin::BI__builtin_abs;
10125 case Builtin::BIfabsf:
10126 case Builtin::BIfabs:
10127 case Builtin::BIfabsl:
10128 case Builtin::BIcabsf:
10129 case Builtin::BIcabs:
10130 case Builtin::BIcabsl:
10131 return Builtin::BIabs;
10137 case Builtin::BI__builtin_abs:
10138 case Builtin::BI__builtin_labs:
10139 case Builtin::BI__builtin_llabs:
10140 case Builtin::BI__builtin_cabsf:
10141 case Builtin::BI__builtin_cabs:
10142 case Builtin::BI__builtin_cabsl:
10143 return Builtin::BI__builtin_fabsf;
10144 case Builtin::BIabs:
10145 case Builtin::BIlabs:
10146 case Builtin::BIllabs:
10147 case Builtin::BIcabsf:
10148 case Builtin::BIcabs:
10149 case Builtin::BIcabsl:
10150 return Builtin::BIfabsf;
10156 case Builtin::BI__builtin_abs:
10157 case Builtin::BI__builtin_labs:
10158 case Builtin::BI__builtin_llabs:
10159 case Builtin::BI__builtin_fabsf:
10160 case Builtin::BI__builtin_fabs:
10161 case Builtin::BI__builtin_fabsl:
10162 return Builtin::BI__builtin_cabsf;
10163 case Builtin::BIabs:
10164 case Builtin::BIlabs:
10165 case Builtin::BIllabs:
10166 case Builtin::BIfabsf:
10167 case Builtin::BIfabs:
10168 case Builtin::BIfabsl:
10169 return Builtin::BIcabsf;
10172 llvm_unreachable(
"Unable to convert function");
10183 case Builtin::BI__builtin_abs:
10184 case Builtin::BI__builtin_fabs:
10185 case Builtin::BI__builtin_fabsf:
10186 case Builtin::BI__builtin_fabsl:
10187 case Builtin::BI__builtin_labs:
10188 case Builtin::BI__builtin_llabs:
10189 case Builtin::BI__builtin_cabs:
10190 case Builtin::BI__builtin_cabsf:
10191 case Builtin::BI__builtin_cabsl:
10192 case Builtin::BIabs:
10193 case Builtin::BIlabs:
10194 case Builtin::BIllabs:
10195 case Builtin::BIfabs:
10196 case Builtin::BIfabsf:
10197 case Builtin::BIfabsl:
10198 case Builtin::BIcabs:
10199 case Builtin::BIcabsf:
10200 case Builtin::BIcabsl:
10203 llvm_unreachable(
"Unknown Builtin type");
10209 unsigned AbsKind,
QualType ArgType) {
10210 bool EmitHeaderHint =
true;
10211 const char *HeaderName =
nullptr;
10212 std::string FunctionName;
10213 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10214 FunctionName =
"std::abs";
10215 if (ArgType->isIntegralOrEnumerationType()) {
10216 HeaderName =
"cstdlib";
10217 }
else if (ArgType->isRealFloatingType()) {
10218 HeaderName =
"cmath";
10220 llvm_unreachable(
"Invalid Type");
10226 R.suppressDiagnostics();
10229 for (
const auto *I : R) {
10232 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10234 FDecl = dyn_cast<FunctionDecl>(I);
10249 EmitHeaderHint =
false;
10261 R.suppressDiagnostics();
10264 if (R.isSingleResult()) {
10265 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10267 EmitHeaderHint =
false;
10271 }
else if (!R.empty()) {
10277 S.
Diag(Loc, diag::note_replace_abs_function)
10283 if (!EmitHeaderHint)
10286 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10290template <std::
size_t StrLen>
10292 const char (&Str)[StrLen]) {
10305 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10306 return llvm::is_contained(names, calleeName);
10311 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10312 "__builtin_nanf16",
"__builtin_nanf128"});
10314 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10315 "__builtin_inff16",
"__builtin_inff128"});
10317 llvm_unreachable(
"unknown MathCheck");
10321 if (FDecl->
getName() !=
"infinity")
10324 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10326 if (RDecl->
getName() !=
"numeric_limits")
10343 if (FPO.getNoHonorNaNs() &&
10346 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10347 << 1 << 0 <<
Call->getSourceRange();
10351 if (FPO.getNoHonorInfs() &&
10355 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10356 << 0 << 0 <<
Call->getSourceRange();
10360void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10362 if (
Call->getNumArgs() != 1)
10367 if (AbsKind == 0 && !IsStdAbs)
10370 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10371 QualType ParamType =
Call->getArg(0)->getType();
10376 std::string FunctionName =
10377 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10378 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10379 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10408 if (ArgValueKind == ParamValueKind) {
10409 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10413 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10414 << FDecl << ArgType << ParamType;
10416 if (NewAbsKind == 0)
10420 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10429 if (NewAbsKind == 0)
10432 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10433 << FDecl << ParamValueKind << ArgValueKind;
10436 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10442 if (!
Call || !FDecl)
return;
10446 if (
Call->getExprLoc().isMacroID())
return;
10449 if (
Call->getNumArgs() != 2)
return;
10452 if (!ArgList)
return;
10453 if (ArgList->size() != 1)
return;
10456 const auto& TA = ArgList->
get(0);
10458 QualType ArgType = TA.getAsType();
10462 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10463 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10464 if (!MTE)
return false;
10465 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10466 if (!
Num)
return false;
10467 if (
Num->getValue() != 0)
return false;
10471 const Expr *FirstArg =
Call->getArg(0);
10472 const Expr *SecondArg =
Call->getArg(1);
10473 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10474 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10477 if (IsFirstArgZero == IsSecondArgZero)
return;
10482 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10484 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10485 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10488 SourceRange RemovalRange;
10489 if (IsFirstArgZero) {
10490 RemovalRange = SourceRange(FirstRange.
getBegin(),
10497 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10512 const auto *Size = dyn_cast<BinaryOperator>(E);
10517 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10521 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10522 << SizeRange << FnName;
10523 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10528 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10539 bool &IsContained) {
10542 IsContained =
false;
10555 for (
auto *FD : RD->
fields()) {
10559 IsContained =
true;
10560 return ContainedRD;
10568 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10569 if (Unary->getKind() == UETT_SizeOf)
10578 if (!
SizeOf->isArgumentType())
10579 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10586 return SizeOf->getTypeOfArgument();
10592struct SearchNonTrivialToInitializeField
10595 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10597 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10600 SourceLocation SL) {
10601 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10602 asDerived().visitArray(PDIK, AT, SL);
10606 Super::visitWithKind(PDIK, FT, SL);
10609 void visitARCStrong(QualType FT, SourceLocation SL) {
10612 void visitARCWeak(QualType FT, SourceLocation SL) {
10615 void visitStruct(QualType FT, SourceLocation SL) {
10620 const ArrayType *AT, SourceLocation SL) {
10621 visit(getContext().getBaseElementType(AT), SL);
10623 void visitTrivial(QualType FT, SourceLocation SL) {}
10625 static void diag(QualType RT,
const Expr *E, Sema &S) {
10626 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10635struct SearchNonTrivialToCopyField
10637 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10639 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10642 SourceLocation SL) {
10643 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10644 asDerived().visitArray(PCK, AT, SL);
10648 Super::visitWithKind(PCK, FT, SL);
10651 void visitARCStrong(QualType FT, SourceLocation SL) {
10654 void visitARCWeak(QualType FT, SourceLocation SL) {
10657 void visitPtrAuth(QualType FT, SourceLocation SL) {
10660 void visitStruct(QualType FT, SourceLocation SL) {
10665 SourceLocation SL) {
10666 visit(getContext().getBaseElementType(AT), SL);
10669 SourceLocation SL) {}
10670 void visitTrivial(QualType FT, SourceLocation SL) {}
10671 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10673 static void diag(QualType RT,
const Expr *E, Sema &S) {
10674 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10689 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10690 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10714 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10716 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10717 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10723 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10726 const Expr *SizeArg =
10727 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10729 auto isLiteralZero = [](
const Expr *E) {
10739 if (isLiteralZero(SizeArg) &&
10746 if (BId == Builtin::BIbzero ||
10749 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10750 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10751 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10752 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10753 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10761 if (BId == Builtin::BImemset &&
10765 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10766 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10771void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10778 unsigned ExpectedNumArgs =
10779 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10780 if (
Call->getNumArgs() < ExpectedNumArgs)
10783 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10784 BId == Builtin::BIstrndup ? 1 : 2);
10786 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10790 Call->getBeginLoc(),
Call->getRParenLoc()))
10802 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10803 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10806 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10810 QualType DestTy = Dest->
getType();
10811 QualType PointeeTy;
10812 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10824 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
10830 if (SizeOfArgTy != QualType()) {
10832 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10834 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10835 << FnName << SizeOfArgTy << ArgIdx
10842 PointeeTy = DestTy;
10845 if (PointeeTy == QualType())
10850 if (
const CXXRecordDecl *ContainedRD =
10853 unsigned OperationType = 0;
10854 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10857 if (ArgIdx != 0 || IsCmp) {
10858 if (BId == Builtin::BImemcpy)
10860 else if(BId == Builtin::BImemmove)
10867 PDiag(diag::warn_dyn_class_memaccess)
10868 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10869 << IsContained << ContainedRD << OperationType
10870 <<
Call->getCallee()->getSourceRange());
10872 BId != Builtin::BImemset)
10875 PDiag(diag::warn_arc_object_memaccess)
10876 << ArgIdx << FnName << PointeeTy
10877 <<
Call->getCallee()->getSourceRange());
10884 bool NonTriviallyCopyableCXXRecord =
10888 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10891 PDiag(diag::warn_cstruct_memaccess)
10892 << ArgIdx << FnName << PointeeTy << 0);
10893 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10894 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10895 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10899 PDiag(diag::warn_cxxstruct_memaccess)
10900 << FnName << PointeeTy);
10901 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10904 PDiag(diag::warn_cstruct_memaccess)
10905 << ArgIdx << FnName << PointeeTy << 1);
10906 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10907 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10908 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10912 PDiag(diag::warn_cxxstruct_memaccess)
10913 << FnName << PointeeTy);
10922 PDiag(diag::note_bad_memaccess_silence)
10928bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
10930 llvm::FoldingSetNodeID SizeOfArgID;
10936 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10939 QualType DestTy = Dest->
getType();
10940 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
10946 if (SizeOfArgID == llvm::FoldingSetNodeID())
10949 llvm::FoldingSetNodeID DestID;
10951 if (DestID == SizeOfArgID) {
10954 unsigned ActionIdx = 0;
10955 StringRef ReadableName = FnName->
getName();
10957 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
10958 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
10967 SourceLocation SL = SizeOfArg->
getExprLoc();
10972 if (
SM.isMacroArgExpansion(SL)) {
10974 SL =
SM.getSpellingLoc(SL);
10975 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10977 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10982 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10983 << ReadableName << PointeeTy << DestTy << DSR
10986 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10987 << ActionIdx << SSR);
11023 if (CAT->getZExtSize() <= 1)
11031void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11035 unsigned NumArgs =
Call->getNumArgs();
11036 if ((NumArgs != 3) && (NumArgs != 4))
11041 const Expr *CompareWithSrc =
nullptr;
11044 Call->getBeginLoc(),
Call->getRParenLoc()))
11049 CompareWithSrc = Ex;
11052 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11053 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11054 SizeCall->getNumArgs() == 1)
11059 if (!CompareWithSrc)
11066 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11070 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11071 if (!CompareWithSrcDRE ||
11075 const Expr *OriginalSizeArg =
Call->getArg(2);
11076 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11083 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11087 SmallString<128> sizeString;
11088 llvm::raw_svector_ostream
OS(sizeString);
11093 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11100 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11101 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11102 return D1->getDecl() == D2->getDecl();
11107 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11116void Sema::CheckStrncatArguments(
const CallExpr *CE,
11131 unsigned PatternType = 0;
11139 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11140 if (BE->getOpcode() == BO_Sub) {
11141 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11142 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11153 if (PatternType == 0)
11162 if (
SM.isMacroArgExpansion(SL)) {
11163 SL =
SM.getSpellingLoc(SL);
11164 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11169 QualType DstTy = DstArg->
getType();
11172 if (!isKnownSizeArray) {
11173 if (PatternType == 1)
11174 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11176 Diag(SL, diag::warn_strncat_src_size) << SR;
11180 if (PatternType == 1)
11181 Diag(SL, diag::warn_strncat_large_size) << SR;
11183 Diag(SL, diag::warn_strncat_src_size) << SR;
11185 SmallString<128> sizeString;
11186 llvm::raw_svector_ostream
OS(sizeString);
11194 Diag(SL, diag::note_strncat_wrong_size)
11199void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11208void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11210 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11211 const Decl *D = Lvalue->getDecl();
11212 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11213 if (!DD->getType()->isReferenceType())
11214 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11218 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11219 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11220 Lvalue->getMemberDecl());
11223void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11225 const auto *Lambda = dyn_cast<LambdaExpr>(
11230 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11231 << CalleeName << 2 ;
11234void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11236 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11237 if (Var ==
nullptr)
11241 << CalleeName << 0 << Var;
11244void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11247 llvm::raw_svector_ostream
OS(SizeString);
11250 if (Kind == clang::CK_BitCast &&
11251 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11253 if (Kind == clang::CK_IntegralToPointer &&
11255 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11258 switch (
Cast->getCastKind()) {
11259 case clang::CK_BitCast:
11260 case clang::CK_IntegralToPointer:
11261 case clang::CK_FunctionToPointerDecay:
11270 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11271 << CalleeName << 0 <<
OS.str();
11275void Sema::CheckFreeArguments(
const CallExpr *E) {
11276 const std::string CalleeName =
11281 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11283 case UnaryOperator::Opcode::UO_AddrOf:
11284 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11285 case UnaryOperator::Opcode::UO_Plus:
11286 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11291 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11293 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11295 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11296 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11297 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11303 << CalleeName << 1 ;
11308 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11309 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11313Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11322 Diag(ReturnLoc, diag::warn_null_ret)
11332 if (Op == OO_New || Op == OO_Array_New) {
11333 const FunctionProtoType *Proto
11337 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11343 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11348 if (
Context.getTargetInfo().getTriple().isPPC64())
11360 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11361 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11362 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11363 return FPLiteral && FPCast;
11366 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11372 llvm::APFloat TargetC = FPLiteral->
getValue();
11373 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11374 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11378 Diag(Loc, diag::warn_float_compare_literal)
11379 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11392 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11393 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11394 if (DRL->getDecl() == DRR->getDecl())
11402 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11403 if (FLL->isExact())
11405 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11406 if (FLR->isExact())
11410 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11411 CL &&
CL->getBuiltinCallee())
11414 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11415 CR && CR->getBuiltinCallee())
11419 Diag(Loc, diag::warn_floatingpoint_eq)
11440 IntRange(
unsigned Width,
bool NonNegative)
11441 : Width(Width), NonNegative(NonNegative) {}
11444 unsigned valueBits()
const {
11445 return NonNegative ? Width : Width - 1;
11449 static IntRange forBoolType() {
11450 return IntRange(1,
true);
11454 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11455 return forValueOfCanonicalType(
C,
11460 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11463 if (
const auto *VT = dyn_cast<VectorType>(T))
11464 T = VT->getElementType().getTypePtr();
11465 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11466 T = MT->getElementType().getTypePtr();
11467 if (
const auto *CT = dyn_cast<ComplexType>(T))
11468 T = CT->getElementType().getTypePtr();
11469 if (
const auto *AT = dyn_cast<AtomicType>(T))
11470 T = AT->getValueType().getTypePtr();
11471 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11472 T = OBT->getUnderlyingType().getTypePtr();
11474 if (!
C.getLangOpts().CPlusPlus) {
11477 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11482 if (
Enum->isFixed()) {
11483 return IntRange(
C.getIntWidth(QualType(T, 0)),
11484 !
Enum->getIntegerType()->isSignedIntegerType());
11487 unsigned NumPositive =
Enum->getNumPositiveBits();
11488 unsigned NumNegative =
Enum->getNumNegativeBits();
11490 if (NumNegative == 0)
11491 return IntRange(NumPositive,
true);
11493 return IntRange(std::max(NumPositive + 1, NumNegative),
11497 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11498 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11511 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11514 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11515 T = VT->getElementType().getTypePtr();
11516 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11517 T = MT->getElementType().getTypePtr();
11518 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11519 T = CT->getElementType().getTypePtr();
11520 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11521 T = AT->getValueType().getTypePtr();
11523 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11524 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11525 T = OBT->getUnderlyingType().getTypePtr();
11527 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11528 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11537 static IntRange join(IntRange L, IntRange R) {
11538 bool Unsigned = L.NonNegative &&
R.NonNegative;
11539 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11540 L.NonNegative &&
R.NonNegative);
11544 static IntRange bit_and(IntRange L, IntRange R) {
11545 unsigned Bits = std::max(L.Width,
R.Width);
11546 bool NonNegative =
false;
11547 if (L.NonNegative) {
11548 Bits = std::min(Bits, L.Width);
11549 NonNegative =
true;
11551 if (
R.NonNegative) {
11552 Bits = std::min(Bits,
R.Width);
11553 NonNegative =
true;
11555 return IntRange(Bits, NonNegative);
11559 static IntRange sum(IntRange L, IntRange R) {
11560 bool Unsigned = L.NonNegative &&
R.NonNegative;
11561 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11566 static IntRange difference(IntRange L, IntRange R) {
11570 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11571 bool Unsigned = L.NonNegative &&
R.Width == 0;
11572 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11578 static IntRange product(IntRange L, IntRange R) {
11582 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11583 bool Unsigned = L.NonNegative &&
R.NonNegative;
11584 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11589 static IntRange rem(IntRange L, IntRange R) {
11593 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11601 if (value.isSigned() && value.isNegative())
11602 return IntRange(value.getSignificantBits(),
false);
11604 if (value.getBitWidth() > MaxWidth)
11605 value = value.trunc(MaxWidth);
11609 return IntRange(value.getActiveBits(),
true);
11613 if (result.
isInt())
11620 R = IntRange::join(R, El);
11628 return IntRange::join(R, I);
11643 Ty = AtomicRHS->getValueType();
11662 bool InConstantContext,
11663 bool Approximate) {
11674 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11675 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11679 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11681 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11682 CE->getCastKind() == CK_BooleanToSignedIntegral;
11685 if (!isIntegerCast)
11686 return OutputTypeRange;
11689 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11690 InConstantContext, Approximate);
11692 return std::nullopt;
11695 if (SubRange->Width >= OutputTypeRange.Width)
11696 return OutputTypeRange;
11700 return IntRange(SubRange->Width,
11701 SubRange->NonNegative || OutputTypeRange.NonNegative);
11704 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11707 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11709 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11710 InConstantContext, Approximate);
11715 Expr *TrueExpr = CO->getTrueExpr();
11717 return std::nullopt;
11719 std::optional<IntRange> L =
11722 return std::nullopt;
11724 Expr *FalseExpr = CO->getFalseExpr();
11726 return std::nullopt;
11728 std::optional<IntRange> R =
11731 return std::nullopt;
11733 return IntRange::join(*L, *R);
11736 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11737 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11739 switch (BO->getOpcode()) {
11741 llvm_unreachable(
"builtin <=> should have class type");
11752 return IntRange::forBoolType();
11781 Combine = IntRange::bit_and;
11789 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11790 if (I->getValue() == 1) {
11791 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11792 return IntRange(R.Width,
true);
11802 case BO_ShrAssign: {
11804 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11806 return std::nullopt;
11810 if (std::optional<llvm::APSInt> shift =
11811 BO->getRHS()->getIntegerConstantExpr(
C)) {
11812 if (shift->isNonNegative()) {
11813 if (shift->uge(L->Width))
11814 L->Width = (L->NonNegative ? 0 : 1);
11816 L->Width -= shift->getZExtValue();
11830 Combine = IntRange::sum;
11834 if (BO->getLHS()->getType()->isPointerType())
11837 Combine = IntRange::difference;
11842 Combine = IntRange::product;
11851 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11853 return std::nullopt;
11856 if (std::optional<llvm::APSInt> divisor =
11857 BO->getRHS()->getIntegerConstantExpr(
C)) {
11858 unsigned log2 = divisor->logBase2();
11859 if (
log2 >= L->Width)
11860 L->Width = (L->NonNegative ? 0 : 1);
11862 L->Width = std::min(L->Width -
log2, MaxWidth);
11870 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11872 return std::nullopt;
11874 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11878 Combine = IntRange::rem;
11890 unsigned opWidth =
C.getIntWidth(T);
11892 InConstantContext, Approximate);
11894 return std::nullopt;
11897 InConstantContext, Approximate);
11899 return std::nullopt;
11901 IntRange
C = Combine(*L, *R);
11902 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
11903 C.Width = std::min(
C.Width, MaxWidth);
11907 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11908 switch (UO->getOpcode()) {
11911 return IntRange::forBoolType();
11925 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11928 return std::nullopt;
11933 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11943 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11946 return std::nullopt;
11951 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11961 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11962 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11966 return IntRange(BitField->getBitWidthValue(),
11967 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11970 return std::nullopt;
11976 bool InConstantContext,
11977 bool Approximate) {
11986 const llvm::fltSemantics &Src,
11987 const llvm::fltSemantics &Tgt) {
11988 llvm::APFloat truncated = value;
11991 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11992 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11994 return truncated.bitwiseIsEqual(value);
12003 const llvm::fltSemantics &Src,
12004 const llvm::fltSemantics &Tgt) {
12028 bool IsListInit =
false);
12043 return MacroName !=
"YES" && MacroName !=
"NO" &&
12044 MacroName !=
"true" && MacroName !=
"false";
12052 (!E->
getType()->isSignedIntegerType() ||
12067struct PromotedRange {
12069 llvm::APSInt PromotedMin;
12071 llvm::APSInt PromotedMax;
12073 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12075 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12076 else if (
R.Width >= BitWidth && !
Unsigned) {
12080 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12081 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12083 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12084 .extOrTrunc(BitWidth);
12085 PromotedMin.setIsUnsigned(
Unsigned);
12087 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12088 .extOrTrunc(BitWidth);
12089 PromotedMax.setIsUnsigned(
Unsigned);
12094 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12104 InRangeFlag = 0x40,
12107 Min =
LE | InRangeFlag,
12108 InRange = InRangeFlag,
12109 Max =
GE | InRangeFlag,
12112 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12117 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12118 Value.isUnsigned() == PromotedMin.isUnsigned());
12119 if (!isContiguous()) {
12120 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12121 if (
Value.isMinValue())
return Min;
12122 if (
Value.isMaxValue())
return Max;
12123 if (
Value >= PromotedMin)
return InRange;
12124 if (
Value <= PromotedMax)
return InRange;
12128 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12129 case -1:
return Less;
12130 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12132 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12133 case -1:
return InRange;
12134 case 0:
return Max;
12139 llvm_unreachable(
"impossible compare result");
12142 static std::optional<StringRef>
12144 if (Op == BO_Cmp) {
12146 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12148 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12149 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12150 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12151 return std::nullopt;
12158 }
else if (Op == BO_NE) {
12162 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12169 if (Op == BO_GE || Op == BO_LE)
12170 std::swap(TrueFlag, FalseFlag);
12173 return StringRef(
"true");
12175 return StringRef(
"false");
12176 return std::nullopt;
12183 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12184 if (ICE->getCastKind() != CK_IntegralCast &&
12185 ICE->getCastKind() != CK_NoOp)
12187 E = ICE->getSubExpr();
12196 enum ConstantValueKind {
12201 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12202 return BL->getValue() ? ConstantValueKind::LiteralTrue
12203 : ConstantValueKind::LiteralFalse;
12204 return ConstantValueKind::Miscellaneous;
12209 const llvm::APSInt &
Value,
12210 bool RhsConstant) {
12226 if (
Constant->getType()->isEnumeralType() &&
12232 if (!OtherValueRange)
12237 OtherT = AT->getValueType();
12238 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12242 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12248 bool OtherIsBooleanDespiteType =
12250 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12251 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12255 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12256 Value.isUnsigned());
12257 auto Cmp = OtherPromotedValueRange.compare(
Value);
12264 bool TautologicalTypeCompare =
false;
12266 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12267 Value.isUnsigned());
12268 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12271 TautologicalTypeCompare =
true;
12279 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12288 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12294 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12295 Other->getType()->isUnsignedIntegerOrEnumerationType())
12296 TautologicalTypeCompare =
true;
12301 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12302 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12306 llvm::raw_svector_ostream OS(PrettySourceValue);
12308 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12309 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12310 Constant->IgnoreParenImpCasts())) {
12311 OS << (BL->getValue() ?
"YES" :
"NO");
12316 if (!TautologicalTypeCompare) {
12318 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12324 if (IsObjCSignedCharBool) {
12326 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12327 << OS.str() << *
Result);
12334 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12338 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12339 : diag::warn_tautological_bool_compare)
12341 << OtherIsBooleanDespiteType << *
Result
12348 ? diag::warn_unsigned_enum_always_true_comparison
12349 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12350 : diag::warn_unsigned_always_true_comparison)
12351 : diag::warn_tautological_constant_compare;
12387 if (T->isIntegralType(S.
Context)) {
12388 std::optional<llvm::APSInt> RHSValue =
12390 std::optional<llvm::APSInt> LHSValue =
12394 if (RHSValue && LHSValue)
12398 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12400 const bool RhsConstant = (
bool)RHSValue;
12401 Expr *Const = RhsConstant ? RHS : LHS;
12403 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12412 if (!T->hasUnsignedIntegerRepresentation()) {
12426 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12428 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12434 Expr *signedOperand, *unsignedOperand;
12437 "unsigned comparison between two signed integer expressions?");
12438 signedOperand = LHS;
12439 unsignedOperand = RHS;
12441 signedOperand = RHS;
12442 unsignedOperand = LHS;
12448 std::optional<IntRange> signedRange =
12460 if (signedRange->NonNegative)
12472 if (!unsignedRange)
12477 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12479 if (unsignedRange->Width < comparisonWidth)
12484 S.
PDiag(diag::warn_mixed_sign_comparison)
12503 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12508 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12509 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12510 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12511 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12512 << BitfieldEnumDecl;
12519 Init->isValueDependent() ||
12520 Init->isTypeDependent())
12523 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12533 const PreferredTypeAttr *PTAttr =
nullptr;
12535 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12537 ED = PTAttr->getType()->getAsEnumDecl();
12545 bool SignedEnum = ED->getNumNegativeBits() > 0;
12552 unsigned DiagID = 0;
12553 if (SignedEnum && !SignedBitfield) {
12556 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12558 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12559 }
else if (SignedBitfield && !SignedEnum &&
12560 ED->getNumPositiveBits() == FieldWidth) {
12563 ? diag::warn_signed_bitfield_enum_conversion
12564 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12567 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12572 << SignedEnum << TypeRange;
12574 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12581 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12582 ED->getNumNegativeBits())
12583 : ED->getNumPositiveBits();
12586 if (BitsNeeded > FieldWidth) {
12590 ? diag::warn_bitfield_too_small_for_enum
12591 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12592 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12596 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12606 unsigned OriginalWidth =
Value.getBitWidth();
12612 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12613 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12620 if (!
Value.isSigned() ||
Value.isNegative())
12621 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12622 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12623 OriginalWidth =
Value.getSignificantBits();
12625 if (OriginalWidth <= FieldWidth)
12629 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12633 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12634 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12638 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12640 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12641 ? diag::warn_impcast_single_bit_bitield_precision_constant
12642 : diag::warn_impcast_bitfield_precision_constant)
12643 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12644 <<
Init->getSourceRange();
12681 bool PruneControlFlow =
false) {
12688 if (T.hasAddressSpace())
12690 if (PruneControlFlow) {
12704 bool PruneControlFlow =
false) {
12711 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12716 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12717 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12722 llvm::APFloat
Value(0.0);
12728 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12733 diag::warn_impcast_float_integer, PruneWarnings);
12736 bool isExact =
false;
12739 T->hasUnsignedIntegerRepresentation());
12740 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
12741 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12749 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12750 precision = (precision * 59 + 195) / 196;
12751 Value.toString(PrettySourceValue, precision);
12755 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12756 << PrettySourceValue);
12759 if (
Result == llvm::APFloat::opOK && isExact) {
12760 if (IsLiteral)
return;
12761 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12767 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
12770 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12771 : diag::warn_impcast_float_to_integer_out_of_range,
12774 unsigned DiagID = 0;
12777 DiagID = diag::warn_impcast_literal_float_to_integer;
12778 }
else if (IntegerValue == 0) {
12779 if (
Value.isZero()) {
12781 diag::warn_impcast_float_integer, PruneWarnings);
12784 DiagID = diag::warn_impcast_float_to_integer_zero;
12786 if (IntegerValue.isUnsigned()) {
12787 if (!IntegerValue.isMaxValue()) {
12789 diag::warn_impcast_float_integer, PruneWarnings);
12792 if (!IntegerValue.isMaxSignedValue() &&
12793 !IntegerValue.isMinSignedValue()) {
12795 diag::warn_impcast_float_integer, PruneWarnings);
12799 DiagID = diag::warn_impcast_float_to_integer;
12804 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12806 IntegerValue.toString(PrettyTargetValue);
12808 if (PruneWarnings) {
12812 << PrettySourceValue << PrettyTargetValue
12825 "Must be compound assignment operation");
12836 ->getComputationResultType()
12843 if (ResultBT->isInteger())
12845 E->
getExprLoc(), diag::warn_impcast_float_integer);
12847 if (!ResultBT->isFloatingPoint())
12856 diag::warn_impcast_float_result_precision);
12861 if (!Range.Width)
return "0";
12863 llvm::APSInt ValueInRange =
Value;
12864 ValueInRange.setIsSigned(!Range.NonNegative);
12865 ValueInRange = ValueInRange.trunc(Range.Width);
12866 return toString(ValueInRange, 10);
12876 const Type *Source =
12878 if (
Target->isDependentType())
12881 const auto *FloatCandidateBT =
12882 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12883 const Type *BoolCandidateType = ToBool ?
Target : Source;
12886 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12891 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12897 S, TheCall->
getArg(I - 1),
false));
12899 S, TheCall->
getArg(I + 1),
false));
12904 diag::warn_impcast_floating_point_to_bool);
12919 if (!IsGNUNullExpr && !HasNullPtrType)
12923 if (T->isAnyPointerType() || T->isBlockPointerType() ||
12924 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
12927 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12940 if (IsGNUNullExpr && Loc.
isMacroID()) {
12943 if (MacroName ==
"NULL")
12951 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12965 const char FirstLiteralCharacter =
12967 if (FirstLiteralCharacter ==
'0')
12973 if (CC.
isValid() && T->isCharType()) {
12974 const char FirstContextCharacter =
12976 if (FirstContextCharacter ==
'{')
12984 const auto *IL = dyn_cast<IntegerLiteral>(E);
12986 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12987 if (UO->getOpcode() == UO_Minus)
12988 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12999 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13003 if (Opc == BO_Shl) {
13006 if (LHS && LHS->getValue() == 0)
13007 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13009 RHS->getValue().isNonNegative() &&
13011 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13012 << (
Result.Val.getInt() != 0);
13014 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13021 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13026 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13027 (RHS->getValue() == 0 || RHS->getValue() == 1))
13030 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13031 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13039 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13045 if (Source->isChar16Type() &&
Target->isChar32Type())
13051 llvm::APSInt
Value(32);
13053 bool IsASCII =
Value <= 0x7F;
13054 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13055 bool ConversionPreservesSemantics =
13056 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13058 if (!ConversionPreservesSemantics) {
13059 auto IsSingleCodeUnitCP = [](
const QualType &T,
13060 const llvm::APSInt &
Value) {
13061 if (T->isChar8Type())
13062 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13063 if (T->isChar16Type())
13064 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13065 assert(T->isChar32Type());
13066 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13069 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13078 LosesPrecision ? diag::warn_impcast_unicode_precision
13079 : diag::warn_impcast_unicode_char_type);
13084 From =
Context.getCanonicalType(From);
13085 To =
Context.getCanonicalType(To);
13088 From = MaybePointee;
13095 if (FromFn->getCFIUncheckedCalleeAttr() &&
13096 !ToFn->getCFIUncheckedCalleeAttr())
13104 bool *ICContext,
bool IsListInit) {
13109 if (Source ==
Target)
return;
13110 if (
Target->isDependentType())
return;
13120 if (Source->isAtomicType())
13124 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13130 diag::warn_impcast_string_literal_to_bool);
13136 diag::warn_impcast_objective_c_literal_to_bool);
13138 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13150 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
13153 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13155 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13164 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13166 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13177 diag::err_impcast_incompatible_type);
13182 ? diag::err_impcast_complex_scalar
13183 : diag::warn_impcast_complex_scalar);
13192 if (
Target->isSveVLSBuiltinType() &&
13199 if (
Target->isRVVVLSBuiltinType() &&
13209 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13217 diag::warn_hlsl_impcast_vector_truncation);
13229 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13230 Target = VecTy->getElementType().getTypePtr();
13234 if (
Target->isScalarType())
13235 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13243 diag::warn_hlsl_impcast_matrix_truncation);
13249 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13250 Target = MatTy->getElementType().getTypePtr();
13252 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13258 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13261 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13263 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13302 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13305 else if (Order < 0) {
13309 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13315 if (TargetBT && TargetBT->
isInteger()) {
13342 diag::warn_impcast_floating_point_to_bool);
13350 if (Source->isFixedPointType()) {
13351 if (
Target->isUnsaturatedFixedPointType()) {
13355 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13356 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13357 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13360 PDiag(diag::warn_impcast_fixed_point_range)
13361 <<
Value.toString() << T
13367 }
else if (
Target->isIntegerType()) {
13371 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13374 llvm::APSInt IntResult = FXResult.convertToInt(
13375 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13380 PDiag(diag::warn_impcast_fixed_point_range)
13381 << FXResult.toString() << T
13388 }
else if (
Target->isUnsaturatedFixedPointType()) {
13389 if (Source->isIntegerType()) {
13396 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13397 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13401 PDiag(diag::warn_impcast_fixed_point_range)
13422 unsigned int SourcePrecision =
SourceRange->Width;
13426 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13429 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13430 SourcePrecision > TargetPrecision) {
13432 if (std::optional<llvm::APSInt> SourceInt =
13437 llvm::APFloat TargetFloatValue(
13439 llvm::APFloat::opStatus ConversionStatus =
13440 TargetFloatValue.convertFromAPInt(
13442 llvm::APFloat::rmNearestTiesToEven);
13444 if (ConversionStatus != llvm::APFloat::opOK) {
13446 SourceInt->toString(PrettySourceValue, 10);
13448 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13452 PDiag(diag::warn_impcast_integer_float_precision_constant)
13453 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13459 diag::warn_impcast_integer_float_precision);
13468 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13473 if (
Target->isBooleanType())
13477 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13481 if (!Source->isIntegerType() || !
Target->isIntegerType())
13486 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13489 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13492 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13497 if (!LikelySourceRange)
13500 IntRange SourceTypeRange =
13501 IntRange::forTargetOfCanonicalType(
Context, Source);
13502 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13504 if (LikelySourceRange->Width > TargetRange.Width) {
13508 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13509 if (TargetOBT->isWrapKind()) {
13516 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13517 if (SourceOBT->isWrapKind()) {
13527 llvm::APSInt
Value(32);
13537 PDiag(diag::warn_impcast_integer_precision_constant)
13538 << PrettySourceValue << PrettyTargetValue
13548 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13549 if (UO->getOpcode() == UO_Minus)
13551 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13554 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13555 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13558 diag::warn_impcast_integer_precision);
13561 if (TargetRange.Width > SourceTypeRange.Width) {
13562 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13563 if (UO->getOpcode() == UO_Minus)
13564 if (Source->isUnsignedIntegerType()) {
13565 if (
Target->isUnsignedIntegerType())
13567 diag::warn_impcast_high_order_zero_bits);
13568 if (
Target->isSignedIntegerType())
13570 diag::warn_impcast_nonnegative_result);
13574 if (TargetRange.Width == LikelySourceRange->Width &&
13575 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13576 Source->isSignedIntegerType()) {
13590 PDiag(diag::warn_impcast_integer_precision_constant)
13591 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13601 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13602 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13603 LikelySourceRange->Width == TargetRange.Width))) {
13607 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13609 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13613 unsigned DiagID = diag::warn_impcast_integer_sign;
13621 DiagID = diag::warn_impcast_integer_sign_conditional;
13633 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13638 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13640 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13641 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13642 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13643 TargetEnum->getDecl()->hasNameForLinkage() &&
13644 SourceEnum != TargetEnum) {
13649 diag::warn_impcast_different_enum_types);
13663 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13676 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13677 TrueExpr = BCO->getCommon();
13679 bool Suspicious =
false;
13683 if (T->isBooleanType())
13688 if (!Suspicious)
return;
13691 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13696 if (E->
getType() == T)
return;
13698 Suspicious =
false;
13703 E->
getType(), CC, &Suspicious);
13720struct AnalyzeImplicitConversionsWorkItem {
13729 bool ExtraCheckForImplicitConversion,
13732 WorkList.push_back({E, CC,
false});
13734 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13741 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13743 Expr *OrigE = Item.E;
13762 Expr *SourceExpr = E;
13767 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13768 if (
auto *Src = OVE->getSourceExpr())
13771 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13772 if (UO->getOpcode() == UO_Not &&
13773 UO->getSubExpr()->isKnownToHaveBooleanValue())
13774 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13778 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13779 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13780 BO->getLHS()->isKnownToHaveBooleanValue() &&
13781 BO->getRHS()->isKnownToHaveBooleanValue() &&
13782 BO->getLHS()->HasSideEffects(S.
Context) &&
13783 BO->getRHS()->HasSideEffects(S.
Context)) {
13794 if (SR.str() ==
"&" || SR.str() ==
"|") {
13796 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13797 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13800 BO->getOperatorLoc(),
13801 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13802 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13804 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13822 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13828 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13834 if (SourceExpr->
getType() != T)
13843 for (
auto *SE : POE->semantics())
13844 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13845 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13849 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13850 E = CE->getSubExpr();
13856 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13857 if (InitListE->getNumInits() == 1) {
13858 E = InitListE->getInit(0);
13865 WorkList.push_back({E, CC, IsListInit});
13869 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13870 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13874 if (OutArgE->isInOut())
13875 WorkList.push_back(
13876 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13877 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13883 if (BO->isComparisonOp())
13887 if (BO->getOpcode() == BO_Assign)
13890 if (BO->isAssignmentOp())
13906 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13908 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13912 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13913 if (ChildExpr == CSE->getOperand())
13919 if (IsLogicalAndOperator &&
13924 WorkList.push_back({ChildExpr, CC, IsListInit});
13938 if (
U->getOpcode() == UO_LNot) {
13940 }
else if (
U->getOpcode() != UO_AddrOf) {
13941 if (
U->getSubExpr()->getType()->isAtomicType())
13942 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13943 diag::warn_atomic_implicit_seq_cst);
13954 WorkList.push_back({OrigE, CC, IsListInit});
13955 while (!WorkList.empty())
13967 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13970 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13971 if (!M->getMemberDecl()->getType()->isReferenceType())
13973 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13974 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13976 FD =
Call->getDirectCallee();
13985 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13999 if (
SM.isMacroBodyExpansion(Loc))
14001 Loc =
SM.getImmediateMacroCallerLoc(Loc);
14025 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14026 : diag::warn_this_bool_conversion;
14031 bool IsAddressOf =
false;
14033 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14034 if (UO->getOpcode() != UO_AddrOf)
14036 IsAddressOf =
true;
14037 E = UO->getSubExpr();
14041 unsigned DiagID = IsCompare
14042 ? diag::warn_address_of_reference_null_compare
14043 : diag::warn_address_of_reference_bool_conversion;
14051 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14054 llvm::raw_string_ostream S(Str);
14056 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14057 : diag::warn_cast_nonnull_to_bool;
14060 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14065 if (
auto *Callee =
Call->getDirectCallee()) {
14066 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14067 ComplainAboutNonnullParamOrCall(A);
14076 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14077 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14078 MRecordDecl && MRecordDecl->isLambda()) {
14081 << MRecordDecl->getSourceRange() << Range << IsEqual;
14091 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14092 D = M->getMemberDecl();
14100 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14103 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14104 ComplainAboutNonnullParamOrCall(A);
14108 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14112 auto ParamIter = llvm::find(FD->
parameters(), PV);
14114 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14118 ComplainAboutNonnullParamOrCall(
NonNull);
14123 if (ArgNo.getASTIndex() == ParamNo) {
14124 ComplainAboutNonnullParamOrCall(
NonNull);
14135 const bool IsFunction = T->isFunctionType();
14138 if (IsAddressOf && IsFunction) {
14143 if (!IsAddressOf && !IsFunction && !IsArray)
14148 llvm::raw_string_ostream S(Str);
14151 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14152 : diag::warn_impcast_pointer_to_bool;
14159 DiagType = AddressOf;
14160 else if (IsFunction)
14161 DiagType = FunctionPointer;
14163 DiagType = ArrayPointer;
14165 llvm_unreachable(
"Could not determine diagnostic.");
14167 << Range << IsEqual;
14180 if (ReturnType.
isNull())
14211 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14212 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14214 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14215 Target->isUnsignedIntegerType()) {
14219 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14220 : diag::warn_impcast_overflow_behavior_pedantic;
14224 ? diag::warn_impcast_overflow_behavior_assignment
14225 : diag::warn_impcast_overflow_behavior;
14231 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14232 if (TargetOBT->isWrapKind()) {
14252 CheckArrayAccess(E);
14262void Sema::CheckForIntOverflow (
const Expr *E) {
14264 SmallVector<const Expr *, 2> Exprs(1, E);
14267 const Expr *OriginalE = Exprs.pop_back_val();
14275 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14276 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14279 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14280 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14281 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14283 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14284 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14285 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14286 Exprs.push_back(Temporary->getSubExpr());
14287 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14288 Exprs.push_back(
Array->getIdx());
14289 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14290 Exprs.push_back(Compound->getInitializer());
14291 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14292 New &&
New->isArray()) {
14293 if (
auto ArraySize =
New->getArraySize())
14294 Exprs.push_back(*ArraySize);
14295 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14296 Exprs.push_back(MTE->getSubExpr());
14297 }
while (!Exprs.empty());
14305 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14312 class SequenceTree {
14314 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14315 unsigned Parent : 31;
14316 LLVM_PREFERRED_TYPE(
bool)
14317 unsigned Merged : 1;
14319 SmallVector<Value, 8> Values;
14325 friend class SequenceTree;
14329 explicit Seq(
unsigned N) : Index(N) {}
14332 Seq() : Index(0) {}
14335 SequenceTree() { Values.push_back(
Value(0)); }
14336 Seq root()
const {
return Seq(0); }
14341 Seq allocate(
Seq Parent) {
14342 Values.push_back(
Value(Parent.Index));
14343 return Seq(Values.size() - 1);
14348 Values[S.Index].Merged =
true;
14354 bool isUnsequenced(
Seq Cur,
Seq Old) {
14355 unsigned C = representative(Cur.Index);
14356 unsigned Target = representative(Old.Index);
14360 C = Values[
C].Parent;
14367 unsigned representative(
unsigned K) {
14368 if (Values[K].Merged)
14370 return Values[K].Parent = representative(Values[K].Parent);
14376 using Object =
const NamedDecl *;
14390 UK_ModAsSideEffect,
14392 UK_Count = UK_ModAsSideEffect + 1
14398 const Expr *UsageExpr =
nullptr;
14399 SequenceTree::Seq
Seq;
14405 Usage Uses[UK_Count];
14408 bool Diagnosed =
false;
14412 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14420 UsageInfoMap UsageMap;
14423 SequenceTree::Seq Region;
14427 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14431 SmallVectorImpl<const Expr *> &WorkList;
14438 struct SequencedSubexpression {
14439 SequencedSubexpression(SequenceChecker &
Self)
14440 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14441 Self.ModAsSideEffect = &ModAsSideEffect;
14444 ~SequencedSubexpression() {
14445 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14449 UsageInfo &UI =
Self.UsageMap[M.first];
14450 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14451 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14452 SideEffectUsage = M.second;
14454 Self.ModAsSideEffect = OldModAsSideEffect;
14457 SequenceChecker &
Self;
14458 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14459 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14466 class EvaluationTracker {
14468 EvaluationTracker(SequenceChecker &
Self)
14470 Self.EvalTracker =
this;
14473 ~EvaluationTracker() {
14474 Self.EvalTracker = Prev;
14476 Prev->EvalOK &= EvalOK;
14479 bool evaluate(
const Expr *E,
bool &
Result) {
14484 Self.SemaRef.isConstantEvaluatedContext());
14489 SequenceChecker &
Self;
14490 EvaluationTracker *Prev;
14491 bool EvalOK =
true;
14492 } *EvalTracker =
nullptr;
14496 Object getObject(
const Expr *E,
bool Mod)
const {
14498 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14499 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14500 return getObject(UO->getSubExpr(), Mod);
14501 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14502 if (BO->getOpcode() == BO_Comma)
14503 return getObject(BO->getRHS(), Mod);
14504 if (Mod && BO->isAssignmentOp())
14505 return getObject(BO->getLHS(), Mod);
14506 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14509 return ME->getMemberDecl();
14510 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14519 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14521 Usage &U = UI.Uses[UK];
14522 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14526 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14527 ModAsSideEffect->push_back(std::make_pair(O, U));
14529 U.UsageExpr = UsageExpr;
14539 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14540 UsageKind OtherKind,
bool IsModMod) {
14544 const Usage &U = UI.Uses[OtherKind];
14545 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14548 const Expr *Mod = U.UsageExpr;
14549 const Expr *ModOrUse = UsageExpr;
14550 if (OtherKind == UK_Use)
14551 std::swap(Mod, ModOrUse);
14555 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14556 : diag::warn_unsequenced_mod_use)
14557 << O << SourceRange(ModOrUse->
getExprLoc()));
14558 UI.Diagnosed =
true;
14587 void notePreUse(
Object O,
const Expr *UseExpr) {
14588 UsageInfo &UI = UsageMap[O];
14590 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14593 void notePostUse(
Object O,
const Expr *UseExpr) {
14594 UsageInfo &UI = UsageMap[O];
14595 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14597 addUsage(O, UI, UseExpr, UK_Use);
14600 void notePreMod(
Object O,
const Expr *ModExpr) {
14601 UsageInfo &UI = UsageMap[O];
14603 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14604 checkUsage(O, UI, ModExpr, UK_Use,
false);
14607 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14608 UsageInfo &UI = UsageMap[O];
14609 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14611 addUsage(O, UI, ModExpr, UK);
14615 SequenceChecker(Sema &S,
const Expr *E,
14616 SmallVectorImpl<const Expr *> &WorkList)
14617 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14621 (void)this->WorkList;
14624 void VisitStmt(
const Stmt *S) {
14628 void VisitExpr(
const Expr *E) {
14630 Base::VisitStmt(E);
14633 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14634 for (
auto *Sub : CSE->
children()) {
14635 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14650 void VisitCastExpr(
const CastExpr *E) {
14662 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14663 const Expr *SequencedAfter) {
14664 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14665 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14666 SequenceTree::Seq OldRegion = Region;
14669 SequencedSubexpression SeqBefore(*
this);
14670 Region = BeforeRegion;
14671 Visit(SequencedBefore);
14674 Region = AfterRegion;
14675 Visit(SequencedAfter);
14677 Region = OldRegion;
14679 Tree.merge(BeforeRegion);
14680 Tree.merge(AfterRegion);
14683 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14688 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14695 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14696 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14697 void VisitBinPtrMem(
const BinaryOperator *BO) {
14702 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14709 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14710 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14711 void VisitBinShlShr(
const BinaryOperator *BO) {
14715 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14722 void VisitBinComma(
const BinaryOperator *BO) {
14727 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14730 void VisitBinAssign(
const BinaryOperator *BO) {
14731 SequenceTree::Seq RHSRegion;
14732 SequenceTree::Seq LHSRegion;
14734 RHSRegion = Tree.allocate(Region);
14735 LHSRegion = Tree.allocate(Region);
14737 RHSRegion = Region;
14738 LHSRegion = Region;
14740 SequenceTree::Seq OldRegion = Region;
14756 SequencedSubexpression SeqBefore(*
this);
14757 Region = RHSRegion;
14761 Region = LHSRegion;
14765 notePostUse(O, BO);
14769 Region = LHSRegion;
14773 notePostUse(O, BO);
14775 Region = RHSRegion;
14783 Region = OldRegion;
14787 : UK_ModAsSideEffect);
14789 Tree.merge(RHSRegion);
14790 Tree.merge(LHSRegion);
14794 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14795 VisitBinAssign(CAO);
14798 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14799 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14800 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14803 return VisitExpr(UO);
14811 : UK_ModAsSideEffect);
14814 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14815 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14816 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14819 return VisitExpr(UO);
14823 notePostMod(O, UO, UK_ModAsSideEffect);
14826 void VisitBinLOr(
const BinaryOperator *BO) {
14832 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14833 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14834 SequenceTree::Seq OldRegion = Region;
14836 EvaluationTracker Eval(*
this);
14838 SequencedSubexpression Sequenced(*
this);
14839 Region = LHSRegion;
14846 bool EvalResult =
false;
14847 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14848 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14849 if (ShouldVisitRHS) {
14850 Region = RHSRegion;
14854 Region = OldRegion;
14855 Tree.merge(LHSRegion);
14856 Tree.merge(RHSRegion);
14859 void VisitBinLAnd(
const BinaryOperator *BO) {
14865 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14866 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14867 SequenceTree::Seq OldRegion = Region;
14869 EvaluationTracker Eval(*
this);
14871 SequencedSubexpression Sequenced(*
this);
14872 Region = LHSRegion;
14878 bool EvalResult =
false;
14879 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14880 bool ShouldVisitRHS = !EvalOK || EvalResult;
14881 if (ShouldVisitRHS) {
14882 Region = RHSRegion;
14886 Region = OldRegion;
14887 Tree.merge(LHSRegion);
14888 Tree.merge(RHSRegion);
14891 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14896 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14912 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14913 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14914 SequenceTree::Seq OldRegion = Region;
14916 EvaluationTracker Eval(*
this);
14918 SequencedSubexpression Sequenced(*
this);
14919 Region = ConditionRegion;
14929 bool EvalResult =
false;
14930 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14931 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14932 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14933 if (ShouldVisitTrueExpr) {
14934 Region = TrueRegion;
14937 if (ShouldVisitFalseExpr) {
14938 Region = FalseRegion;
14942 Region = OldRegion;
14943 Tree.merge(ConditionRegion);
14944 Tree.merge(TrueRegion);
14945 Tree.merge(FalseRegion);
14948 void VisitCallExpr(
const CallExpr *CE) {
14960 SequencedSubexpression Sequenced(*
this);
14965 SequenceTree::Seq CalleeRegion;
14966 SequenceTree::Seq OtherRegion;
14967 if (SemaRef.getLangOpts().CPlusPlus17) {
14968 CalleeRegion = Tree.allocate(Region);
14969 OtherRegion = Tree.allocate(Region);
14971 CalleeRegion = Region;
14972 OtherRegion = Region;
14974 SequenceTree::Seq OldRegion = Region;
14977 Region = CalleeRegion;
14979 SequencedSubexpression Sequenced(*this);
14980 Visit(CE->getCallee());
14982 Visit(CE->getCallee());
14986 Region = OtherRegion;
14990 Region = OldRegion;
14992 Tree.merge(CalleeRegion);
14993 Tree.merge(OtherRegion);
15011 return VisitCallExpr(CXXOCE);
15022 case OO_MinusEqual:
15024 case OO_SlashEqual:
15025 case OO_PercentEqual:
15026 case OO_CaretEqual:
15029 case OO_LessLessEqual:
15030 case OO_GreaterGreaterEqual:
15031 SequencingKind = RHSBeforeLHS;
15035 case OO_GreaterGreater:
15041 SequencingKind = LHSBeforeRHS;
15045 SequencingKind = LHSBeforeRest;
15049 SequencingKind = NoSequencing;
15053 if (SequencingKind == NoSequencing)
15054 return VisitCallExpr(CXXOCE);
15057 SequencedSubexpression Sequenced(*
this);
15060 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15061 "Should only get there with C++17 and above!");
15062 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15063 "Should only get there with an overloaded binary operator"
15064 " or an overloaded call operator!");
15066 if (SequencingKind == LHSBeforeRest) {
15067 assert(CXXOCE->getOperator() == OO_Call &&
15068 "We should only have an overloaded call operator here!");
15077 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15078 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15079 SequenceTree::Seq OldRegion = Region;
15081 assert(CXXOCE->getNumArgs() >= 1 &&
15082 "An overloaded call operator must have at least one argument"
15083 " for the postfix-expression!");
15084 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15085 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15086 CXXOCE->getNumArgs() - 1);
15090 Region = PostfixExprRegion;
15091 SequencedSubexpression Sequenced(*this);
15092 Visit(PostfixExpr);
15096 Region = ArgsRegion;
15097 for (const Expr *Arg : Args)
15100 Region = OldRegion;
15101 Tree.merge(PostfixExprRegion);
15102 Tree.merge(ArgsRegion);
15104 assert(CXXOCE->getNumArgs() == 2 &&
15105 "Should only have two arguments here!");
15106 assert((SequencingKind == LHSBeforeRHS ||
15107 SequencingKind == RHSBeforeLHS) &&
15108 "Unexpected sequencing kind!");
15112 const Expr *E1 = CXXOCE->getArg(0);
15113 const Expr *E2 = CXXOCE->getArg(1);
15114 if (SequencingKind == RHSBeforeLHS)
15117 return VisitSequencedExpressions(E1, E2);
15124 SequencedSubexpression Sequenced(*
this);
15127 return VisitExpr(CCE);
15130 SequenceExpressionsInOrder(
15136 return VisitExpr(ILE);
15139 SequenceExpressionsInOrder(ILE->
inits());
15151 SequenceTree::Seq Parent = Region;
15152 for (
const Expr *E : ExpressionList) {
15155 Region = Tree.allocate(Parent);
15156 Elts.push_back(Region);
15162 for (
unsigned I = 0; I < Elts.size(); ++I)
15163 Tree.merge(Elts[I]);
15167SequenceChecker::UsageInfo::UsageInfo() =
default;
15171void Sema::CheckUnsequencedOperations(
const Expr *E) {
15172 SmallVector<const Expr *, 8> WorkList;
15173 WorkList.push_back(E);
15174 while (!WorkList.empty()) {
15175 const Expr *Item = WorkList.pop_back_val();
15176 SequenceChecker(*
this, Item, WorkList);
15181 bool IsConstexpr) {
15184 CheckImplicitConversions(E, CheckLoc);
15186 CheckUnsequencedOperations(E);
15188 CheckForIntOverflow(E);
15201 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15205 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15209 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15223 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15227 bool CheckParameterNames) {
15228 bool HasInvalidParm =
false;
15230 assert(Param &&
"null in a parameter list");
15239 if (!Param->isInvalidDecl() &&
15241 diag::err_typecheck_decl_incomplete_type) ||
15243 diag::err_abstract_type_in_decl,
15245 Param->setInvalidDecl();
15246 HasInvalidParm =
true;
15251 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15255 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15263 QualType PType = Param->getOriginalType();
15271 if (!Param->isInvalidDecl()) {
15272 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15273 if (!ClassDecl->isInvalidDecl() &&
15274 !ClassDecl->hasIrrelevantDestructor() &&
15275 !ClassDecl->isDependentContext() &&
15276 ClassDecl->isParamDestroyedInCallee()) {
15288 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15289 if (!Param->getType().isConstQualified())
15290 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15294 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15299 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15300 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15305 if (!Param->isInvalidDecl() &&
15306 Param->getOriginalType()->isWebAssemblyTableType()) {
15307 Param->setInvalidDecl();
15308 HasInvalidParm =
true;
15309 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15313 return HasInvalidParm;
15316std::optional<std::pair<
15325static std::pair<CharUnits, CharUnits>
15333 if (
Base->isVirtual()) {
15340 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15347 DerivedType =
Base->getType();
15350 return std::make_pair(BaseAlignment, Offset);
15354static std::optional<std::pair<CharUnits, CharUnits>>
15360 return std::nullopt;
15365 return std::nullopt;
15369 CharUnits Offset = EltSize * IdxRes->getExtValue();
15372 return std::make_pair(P->first, P->second + Offset);
15378 return std::make_pair(
15379 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15385std::optional<std::pair<
15393 case Stmt::CStyleCastExprClass:
15394 case Stmt::CXXStaticCastExprClass:
15395 case Stmt::ImplicitCastExprClass: {
15397 const Expr *From = CE->getSubExpr();
15398 switch (CE->getCastKind()) {
15403 case CK_UncheckedDerivedToBase:
15404 case CK_DerivedToBase: {
15414 case Stmt::ArraySubscriptExprClass: {
15419 case Stmt::DeclRefExprClass: {
15423 if (!VD->getType()->isReferenceType()) {
15425 if (VD->hasDependentAlignment())
15434 case Stmt::MemberExprClass: {
15436 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15440 std::optional<std::pair<CharUnits, CharUnits>> P;
15449 return std::make_pair(P->first,
15452 case Stmt::UnaryOperatorClass: {
15462 case Stmt::BinaryOperatorClass: {
15474 return std::nullopt;
15479std::optional<std::pair<
15488 case Stmt::CStyleCastExprClass:
15489 case Stmt::CXXStaticCastExprClass:
15490 case Stmt::ImplicitCastExprClass: {
15492 const Expr *From = CE->getSubExpr();
15493 switch (CE->getCastKind()) {
15498 case CK_ArrayToPointerDecay:
15500 case CK_UncheckedDerivedToBase:
15501 case CK_DerivedToBase: {
15511 case Stmt::CXXThisExprClass: {
15516 case Stmt::UnaryOperatorClass: {
15522 case Stmt::BinaryOperatorClass: {
15531 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15532 std::swap(LHS, RHS);
15542 return std::nullopt;
15547 std::optional<std::pair<CharUnits, CharUnits>> P =
15551 return P->first.alignmentAtOffset(P->second);
15569 if (!DestPtr)
return;
15575 if (DestAlign.
isOne())
return;
15579 if (!SrcPtr)
return;
15590 if (SrcAlign >= DestAlign)
return;
15595 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15599void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15601 bool AllowOnePastEnd,
bool IndexNegated) {
15610 const Type *EffectiveType =
15614 Context.getAsConstantArrayType(BaseExpr->
getType());
15617 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15619 const Type *BaseType =
15621 bool IsUnboundedArray =
15623 Context, StrictFlexArraysLevel,
15626 (!IsUnboundedArray && BaseType->isDependentType()))
15634 if (IndexNegated) {
15635 index.setIsUnsigned(
false);
15639 if (IsUnboundedArray) {
15642 if (
index.isUnsigned() || !
index.isNegative()) {
15644 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15646 if (
index.getBitWidth() < AddrBits)
15648 std::optional<CharUnits> ElemCharUnits =
15649 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15652 if (!ElemCharUnits || ElemCharUnits->isZero())
15654 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15659 if (
index.getActiveBits() <= AddrBits) {
15661 llvm::APInt Product(
index);
15663 Product = Product.umul_ov(ElemBytes, Overflow);
15664 if (!Overflow && Product.getActiveBits() <= AddrBits)
15670 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15671 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15673 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15674 MaxElems = MaxElems.udiv(ElemBytes);
15677 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15678 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15683 PDiag(DiagID) << index << AddrBits
15684 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15685 << ElemBytes << MaxElems
15686 << MaxElems.getZExtValue()
15689 const NamedDecl *ND =
nullptr;
15691 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15693 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15695 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15696 ND = ME->getMemberDecl();
15700 PDiag(diag::note_array_declared_here) << ND);
15705 if (index.isUnsigned() || !index.isNegative()) {
15715 llvm::APInt size = ArrayTy->
getSize();
15717 if (BaseType != EffectiveType) {
15725 if (!ptrarith_typesize)
15726 ptrarith_typesize =
Context.getCharWidth();
15728 if (ptrarith_typesize != array_typesize) {
15730 uint64_t ratio = array_typesize / ptrarith_typesize;
15734 if (ptrarith_typesize * ratio == array_typesize)
15735 size *= llvm::APInt(size.getBitWidth(), ratio);
15739 if (size.getBitWidth() > index.getBitWidth())
15740 index = index.zext(size.getBitWidth());
15741 else if (size.getBitWidth() < index.getBitWidth())
15742 size = size.zext(index.getBitWidth());
15748 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15755 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15757 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15758 SourceLocation IndexLoc =
15760 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15765 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15766 : diag::warn_ptr_arith_exceeds_bounds;
15767 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15768 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15772 << index << ArrayTy->
desugar() << CastMsg
15775 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15777 DiagID = diag::warn_ptr_arith_precedes_bounds;
15778 if (index.isNegative()) index = -index;
15785 const NamedDecl *ND =
nullptr;
15787 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15789 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15791 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15792 ND = ME->getMemberDecl();
15796 PDiag(diag::note_array_declared_here) << ND);
15799void Sema::CheckArrayAccess(
const Expr *
expr) {
15800 int AllowOnePastEnd = 0;
15802 expr =
expr->IgnoreParenImpCasts();
15803 switch (
expr->getStmtClass()) {
15804 case Stmt::ArraySubscriptExprClass: {
15807 AllowOnePastEnd > 0);
15811 case Stmt::MemberExprClass: {
15815 case Stmt::CXXMemberCallExprClass: {
15819 case Stmt::ArraySectionExprClass: {
15825 nullptr, AllowOnePastEnd > 0);
15828 case Stmt::UnaryOperatorClass: {
15844 case Stmt::ConditionalOperatorClass: {
15846 if (
const Expr *lhs = cond->
getLHS())
15847 CheckArrayAccess(lhs);
15848 if (
const Expr *rhs = cond->
getRHS())
15849 CheckArrayAccess(rhs);
15852 case Stmt::CXXOperatorCallExprClass: {
15854 for (
const auto *Arg : OCE->arguments())
15855 CheckArrayAccess(Arg);
15865 Expr *RHS,
bool isProperty) {
15877 S.
Diag(Loc, diag::warn_arc_literal_assign)
15879 << (isProperty ? 0 : 1)
15887 Expr *RHS,
bool isProperty) {
15890 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15891 S.
Diag(Loc, diag::warn_arc_retained_assign)
15893 << (isProperty ? 0 : 1)
15897 RHS =
cast->getSubExpr();
15939 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15968 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15969 Diag(Loc, diag::warn_arc_retained_property_assign)
15973 RHS =
cast->getSubExpr();
15996 bool StmtLineInvalid;
15997 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15999 if (StmtLineInvalid)
16002 bool BodyLineInvalid;
16003 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16005 if (BodyLineInvalid)
16009 if (StmtLine != BodyLine)
16024 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16033 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16037 const Stmt *PossibleBody) {
16043 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16044 StmtLoc = FS->getRParenLoc();
16045 Body = FS->getBody();
16046 DiagID = diag::warn_empty_for_body;
16047 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16048 StmtLoc = WS->getRParenLoc();
16049 Body = WS->getBody();
16050 DiagID = diag::warn_empty_while_body;
16055 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16079 if (!ProbableTypo) {
16080 bool BodyColInvalid;
16081 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16083 if (BodyColInvalid)
16086 bool StmtColInvalid;
16089 if (StmtColInvalid)
16092 if (BodyCol > StmtCol)
16093 ProbableTypo =
true;
16096 if (ProbableTypo) {
16098 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16106 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16118 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16120 RHSExpr = CE->
getArg(0);
16121 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16122 CXXSCE && CXXSCE->isXValue())
16123 RHSExpr = CXXSCE->getSubExpr();
16127 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16128 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16131 if (LHSDeclRef && RHSDeclRef) {
16138 auto D =
Diag(OpLoc, diag::warn_self_move)
16154 const Expr *LHSBase = LHSExpr;
16155 const Expr *RHSBase = RHSExpr;
16156 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16157 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16158 if (!LHSME || !RHSME)
16161 while (LHSME && RHSME) {
16168 LHSME = dyn_cast<MemberExpr>(LHSBase);
16169 RHSME = dyn_cast<MemberExpr>(RHSBase);
16172 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16173 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16174 if (LHSDeclRef && RHSDeclRef) {
16181 Diag(OpLoc, diag::warn_self_move)
16188 Diag(OpLoc, diag::warn_self_move)
16212 bool AreUnionMembers =
false) {
16216 assert(((Field1Parent->isStructureOrClassType() &&
16217 Field2Parent->isStructureOrClassType()) ||
16218 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16219 "Can't evaluate layout compatibility between a struct field and a "
16221 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16222 (AreUnionMembers && Field1Parent->isUnionType())) &&
16223 "AreUnionMembers should be 'true' for union fields (only).");
16237 if (Bits1 != Bits2)
16241 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16242 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16245 if (!AreUnionMembers &&
16257 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16258 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16260 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16261 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16266 return isLayoutCompatible(C, F1, F2);
16277 for (
auto *Field1 : RD1->
fields()) {
16278 auto I = UnmatchedFields.begin();
16279 auto E = UnmatchedFields.end();
16281 for ( ; I != E; ++I) {
16283 bool Result = UnmatchedFields.erase(*I);
16293 return UnmatchedFields.empty();
16319 if (
C.hasSameType(T1, T2))
16328 if (TC1 == Type::Enum)
16330 if (TC1 == Type::Record) {
16349 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16380 const ValueDecl **VD, uint64_t *MagicValue,
16381 bool isConstantEvaluated) {
16389 case Stmt::UnaryOperatorClass: {
16398 case Stmt::DeclRefExprClass: {
16404 case Stmt::IntegerLiteralClass: {
16406 llvm::APInt MagicValueAPInt = IL->
getValue();
16407 if (MagicValueAPInt.getActiveBits() <= 64) {
16408 *MagicValue = MagicValueAPInt.getZExtValue();
16414 case Stmt::BinaryConditionalOperatorClass:
16415 case Stmt::ConditionalOperatorClass: {
16420 isConstantEvaluated)) {
16430 case Stmt::BinaryOperatorClass: {
16433 TypeExpr = BO->
getRHS();
16463 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16466 bool isConstantEvaluated) {
16467 FoundWrongKind =
false;
16472 uint64_t MagicValue;
16474 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16478 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16479 if (I->getArgumentKind() != ArgumentKind) {
16480 FoundWrongKind =
true;
16483 TypeInfo.Type = I->getMatchingCType();
16484 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16485 TypeInfo.MustBeNull = I->getMustBeNull();
16496 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16497 if (I == MagicValues->end())
16506 bool LayoutCompatible,
16508 if (!TypeTagForDatatypeMagicValues)
16509 TypeTagForDatatypeMagicValues.reset(
16510 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16513 (*TypeTagForDatatypeMagicValues)[Magic] =
16529 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16530 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16531 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16532 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16535void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16538 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16539 bool IsPointerAttr = Attr->getIsPointer();
16542 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16543 if (TypeTagIdxAST >= ExprArgs.size()) {
16544 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16545 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16548 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16549 bool FoundWrongKind;
16552 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16554 if (FoundWrongKind)
16556 diag::warn_type_tag_for_datatype_wrong_kind)
16562 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16563 if (ArgumentIdxAST >= ExprArgs.size()) {
16564 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16565 << 1 << Attr->getArgumentIdx().getSourceIndex();
16568 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16569 if (IsPointerAttr) {
16571 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16572 if (ICE->getType()->isVoidPointerType() &&
16573 ICE->getCastKind() == CK_BitCast)
16574 ArgumentExpr = ICE->getSubExpr();
16576 QualType ArgumentType = ArgumentExpr->
getType();
16582 if (TypeInfo.MustBeNull) {
16587 diag::warn_type_safety_null_pointer_required)
16595 QualType RequiredType = TypeInfo.Type;
16597 RequiredType =
Context.getPointerType(RequiredType);
16599 bool mismatch =
false;
16600 if (!TypeInfo.LayoutCompatible) {
16601 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16622 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16623 << ArgumentType << ArgumentKind
16624 << TypeInfo.LayoutCompatible << RequiredType
16642 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16650 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16656 auto &MisalignedMembersForExpr =
16658 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16659 if (MA != MisalignedMembersForExpr.end() &&
16660 (T->isDependentType() || T->isIntegerType() ||
16661 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16663 T->getPointeeType()) <= MA->Alignment))))
16664 MisalignedMembersForExpr.erase(MA);
16673 const auto *ME = dyn_cast<MemberExpr>(E);
16685 bool AnyIsPacked =
false;
16687 QualType BaseType = ME->getBase()->getType();
16688 if (BaseType->isDependentType())
16692 auto *RD = BaseType->castAsRecordDecl();
16697 auto *FD = dyn_cast<FieldDecl>(MD);
16703 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16704 ReverseMemberChain.push_back(FD);
16707 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16709 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16716 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16727 if (ExpectedAlignment.
isOne())
16732 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16733 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16737 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16741 if (DRE && !TopME->
isArrow()) {
16744 CompleteObjectAlignment =
16745 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16749 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16752 CompleteObjectAlignment < ExpectedAlignment) {
16763 for (
FieldDecl *FDI : ReverseMemberChain) {
16764 if (FDI->hasAttr<PackedAttr>() ||
16765 FDI->getParent()->hasAttr<PackedAttr>()) {
16767 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16773 assert(FD &&
"We did not find a packed FieldDecl!");
16774 Action(E, FD->
getParent(), FD, Alignment);
16778void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16779 using namespace std::placeholders;
16782 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16806bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16807 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16834 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16851 assert(!Args.empty() &&
"Should have at least one argument.");
16853 Expr *Arg0 = Args.front();
16856 auto EmitError = [&](
Expr *ArgI) {
16858 diag::err_typecheck_call_different_arg_types)
16859 << Arg0->
getType() << ArgI->getType();
16864 for (
Expr *ArgI : Args.drop_front())
16875 for (
Expr *ArgI : Args.drop_front()) {
16876 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16879 VecI->getElementType()) ||
16880 Vec0->getNumElements() != VecI->getNumElements()) {
16889std::optional<QualType>
16893 return std::nullopt;
16897 return std::nullopt;
16900 for (
int I = 0; I < 2; ++I) {
16904 return std::nullopt;
16905 Args[I] = Converted.
get();
16912 return std::nullopt;
16915 return std::nullopt;
16917 TheCall->
setArg(0, Args[0]);
16918 TheCall->
setArg(1, Args[1]);
16929 TheCall->
getArg(1), Loc) ||
16931 TheCall->
getArg(2), Loc))
16935 for (
int I = 0; I < 3; ++I) {
16940 Args[I] = Converted.
get();
16943 int ArgOrdinal = 1;
16944 for (
Expr *Arg : Args) {
16946 ArgTyRestr, ArgOrdinal++))
16953 for (
int I = 0; I < 3; ++I)
16954 TheCall->
setArg(I, Args[I]);
16960bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16972bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16981 diag::err_builtin_invalid_arg_type)
16982 << 1 << 2 << 1 << 1 << TyArg;
16996 Expr *Matrix = MatrixArg.
get();
16998 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17001 << 1 << 3 << 0 << 0
17008 QualType ResultType =
Context.getConstantMatrixType(
17009 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17012 TheCall->
setType(ResultType);
17015 TheCall->
setArg(0, Matrix);
17020static std::optional<unsigned>
17028 uint64_t
Dim =
Value->getZExtValue();
17044 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17046 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17054 unsigned PtrArgIdx = 0;
17055 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17056 Expr *RowsExpr = TheCall->
getArg(1);
17057 Expr *ColumnsExpr = TheCall->
getArg(2);
17058 Expr *StrideExpr = TheCall->
getArg(3);
17060 bool ArgError =
false;
17067 PtrExpr = PtrConv.
get();
17068 TheCall->
setArg(0, PtrExpr);
17075 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17076 QualType ElementTy;
17079 << PtrArgIdx + 1 << 0 << 5 << 0
17083 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17087 << PtrArgIdx + 1 << 0 << 5
17094 auto ApplyArgumentConversions = [
this](Expr *E) {
17103 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17105 RowsExpr = RowsConv.
get();
17106 TheCall->
setArg(1, RowsExpr);
17108 RowsExpr =
nullptr;
17110 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17112 ColumnsExpr = ColumnsConv.
get();
17113 TheCall->
setArg(2, ColumnsExpr);
17115 ColumnsExpr =
nullptr;
17126 std::optional<unsigned> MaybeRows;
17130 std::optional<unsigned> MaybeColumns;
17135 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17138 StrideExpr = StrideConv.
get();
17139 TheCall->
setArg(3, StrideExpr);
17142 if (std::optional<llvm::APSInt>
Value =
17145 if (Stride < *MaybeRows) {
17147 diag::err_builtin_matrix_stride_too_small);
17153 if (ArgError || !MaybeRows || !MaybeColumns)
17157 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17168 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17170 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17178 unsigned PtrArgIdx = 1;
17179 Expr *MatrixExpr = TheCall->
getArg(0);
17180 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17181 Expr *StrideExpr = TheCall->
getArg(2);
17183 bool ArgError =
false;
17189 MatrixExpr = MatrixConv.
get();
17190 TheCall->
setArg(0, MatrixExpr);
17197 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17200 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17208 PtrExpr = PtrConv.
get();
17209 TheCall->
setArg(1, PtrExpr);
17217 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17220 << PtrArgIdx + 1 << 0 << 5 << 0
17224 QualType ElementTy = PtrTy->getPointeeType();
17226 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17231 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17233 diag::err_builtin_matrix_pointer_arg_mismatch)
17234 << ElementTy << MatrixTy->getElementType();
17249 StrideExpr = StrideConv.
get();
17250 TheCall->
setArg(2, StrideExpr);
17255 if (std::optional<llvm::APSInt>
Value =
17258 if (Stride < MatrixTy->getNumRows()) {
17260 diag::err_builtin_matrix_stride_too_small);
17280 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17285 llvm::StringSet<> CalleeTCBs;
17286 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17287 CalleeTCBs.insert(A->getTCBName());
17288 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17289 CalleeTCBs.insert(A->getTCBName());
17293 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17294 StringRef CallerTCB = A->getTCBName();
17295 if (CalleeTCBs.count(CallerTCB) == 0) {
17296 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17297 << 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.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool BuiltinRotateGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_stdc_rotate_{left,right} was called with two arguments, that the first argument...
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool isValidMathElementType(QualType T)
static void DiagnoseDeprecatedHIPAtomic(Sema &S, SourceRange ExprRange, MultiExprArg Args, AtomicExpr::AtomicOp Op)
Deprecate __hip_atomic_* builtins in favour of __scoped_atomic_* equivalents.
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)
#define HIP_ATOMIC_FIXABLE(hip, scoped)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static QualType getVectorElementType(ASTContext &Context, QualType VecTy)
static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
static bool BuiltinBitreverseg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bitreverseg was called with a single argument, which is an integer.
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static bool CheckMissingFormatAttribute(Sema *S, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, StringLiteral *ReferenceFormatString, unsigned FormatIdx, unsigned FirstDataArg, FormatStringType FormatType, unsigned CallerParamIdx, SourceLocation Loc)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall)
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, std::optional< unsigned > *CallerFormatParamIdx=nullptr, bool IgnoreStringsWithoutSpecifiers=false)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call)
static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall, QualType ReturnType)
Checks the __builtin_stdc_* builtins that take a single unsigned integer argument and return either i...
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 for SYCL constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
unsigned getLength() const
const char * toString() const
const char * getStart() const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
void toString(raw_ostream &os) const
Sema::SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when the only matching conversion function is explicit.
Sema::SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when the expression has incomplete class type.
Sema::SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for one of the candidate conversions.
Sema::SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when there are multiple possible conversion functions.
Sema::SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic complaining that the expression does not have integral or enumeration type.
RotateIntegerConverter(unsigned ArgIndex, bool OnlyUnsigned)
Sema::SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when we picked a conversion function (for cases when we are not allowed to pick a ...
Sema::SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for the explicit conversion function.
bool match(QualType T) override
Determine whether the specified type is a valid destination type for this conversion.
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APValue & getMatrixElt(unsigned Idx)
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
unsigned getMatrixNumElements() const
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedShortTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ conversion function within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getEndLoc() const
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
ConditionalOperator - The ?
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
Expr * getOperand() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getBeginLoc() const
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isFlexibleArrayMemberLike(const ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits() const
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
UnresolvedSetImpl::iterator iterator
Represents a matrix type, as defined in the Matrix Types clang extensions.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
bool CheckOverflowBehaviorTypeConversion(Expr *E, QualType T, SourceLocation CC)
Check for overflow behavior type related implicit conversion diagnostics.
FPOptionsOverride CurFPFeatureOverrides()
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
DiagnosticsEngine & getDiagnostics() const
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
bool InOverflowBehaviorAssignmentContext
Track if we're currently analyzing overflow behavior types in assignment context.
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isMatrixType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
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
bool isFunctionOrMethodVariadic(const Decl *D)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
unsigned Indentation
The number of spaces to use to indent each line.
unsigned AnonymousTagNameStyle
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.