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);
559 return getStringLiteral(
T.getAsString(Policy));
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));
1152class FortifiedBufferChecker {
1154 FortifiedBufferChecker(Sema &S, FunctionDecl *FD, CallExpr *TheCall)
1155 : S(S), TheCall(TheCall), FD(FD),
1156 DABAttr(FD ? FD->getAttr<DiagnoseAsBuiltinAttr>() :
nullptr) {
1161 std::optional<unsigned> TranslateIndex(
unsigned Index) {
1168 unsigned DABIndices = DABAttr->argIndices_size();
1169 unsigned NewIndex = Index < DABIndices
1170 ? DABAttr->argIndices_begin()[Index]
1173 return std::nullopt;
1177 std::optional<llvm::APSInt>
1178 ComputeExplicitObjectSizeArgument(
unsigned Index) {
1179 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1181 return std::nullopt;
1182 unsigned NewIndex = *IndexOptional;
1184 Expr *SizeArg = TheCall->
getArg(NewIndex);
1186 return std::nullopt;
1187 llvm::APSInt
Integer =
Result.Val.getInt().extOrTrunc(SizeTypeWidth);
1192 std::optional<llvm::APSInt> ComputeSizeArgument(
unsigned Index) {
1198 if (Index < FD->getNumParams()) {
1199 if (
const auto *POS =
1201 BOSType = POS->getType();
1204 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1206 return std::nullopt;
1207 unsigned NewIndex = *IndexOptional;
1210 return std::nullopt;
1212 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1213 if (std::optional<uint64_t> ObjSize =
1216 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1218 return std::nullopt;
1221 std::optional<llvm::APSInt> ComputeStrLenArgument(
unsigned Index) {
1222 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1224 return std::nullopt;
1225 unsigned NewIndex = *IndexOptional;
1227 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1229 if (std::optional<uint64_t>
Result =
1232 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1234 return std::nullopt;
1237 unsigned getSizeTypeWidth()
const {
return SizeTypeWidth; }
1239 unsigned getBuiltinID()
const {
1240 const FunctionDecl *UseDecl = FD;
1242 UseDecl = DABAttr->getFunction();
1243 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1250 unsigned ID = getBuiltinID();
1254 assert(Callee &&
"expected callee");
1255 return Callee->getName().str();
1258 StringRef Ref = Name;
1260 if (!(Ref.consume_front(
"__builtin___") && Ref.consume_back(
"_chk")))
1261 Ref.consume_front(
"__builtin_");
1262 assert(!Ref.empty() &&
"expected non-empty function name");
1267 void checkSourceOverread(
unsigned SrcArgIdx,
unsigned SizeArgIdx) {
1271 const Expr *SrcArg = TheCall->
getArg(SrcArgIdx);
1272 const Expr *SizeArg = TheCall->
getArg(SizeArgIdx);
1277 std::optional<llvm::APSInt> CopyLen =
1278 ComputeExplicitObjectSizeArgument(SizeArgIdx);
1279 std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx);
1281 if (!CopyLen || !SrcBufSize)
1285 if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0)
1289 S.
PDiag(diag::warn_stringop_overread)
1291 << SrcBufSize->getZExtValue());
1298 const DiagnoseAsBuiltinAttr *DABAttr;
1299 unsigned SizeTypeWidth;
1303void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1308 FortifiedBufferChecker Checker(*
this, FD, TheCall);
1310 unsigned BuiltinID = Checker.getBuiltinID();
1314 unsigned SizeTypeWidth = Checker.getSizeTypeWidth();
1316 std::optional<llvm::APSInt> SourceSize;
1317 std::optional<llvm::APSInt> DestinationSize;
1318 unsigned DiagID = 0;
1320 switch (BuiltinID) {
1323 case Builtin::BI__builtin_strcat:
1324 case Builtin::BIstrcat:
1325 case Builtin::BI__builtin_stpcpy:
1326 case Builtin::BIstpcpy:
1327 case Builtin::BI__builtin_strcpy:
1328 case Builtin::BIstrcpy: {
1329 DiagID = diag::warn_fortify_strlen_overflow;
1330 SourceSize = Checker.ComputeStrLenArgument(1);
1331 DestinationSize = Checker.ComputeSizeArgument(0);
1335 case Builtin::BI__builtin___strcat_chk:
1336 case Builtin::BI__builtin___stpcpy_chk:
1337 case Builtin::BI__builtin___strcpy_chk: {
1338 DiagID = diag::warn_fortify_strlen_overflow;
1339 SourceSize = Checker.ComputeStrLenArgument(1);
1340 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1344 case Builtin::BIscanf:
1345 case Builtin::BIfscanf:
1346 case Builtin::BIsscanf: {
1347 unsigned FormatIndex = 1;
1348 unsigned DataIndex = 2;
1349 if (BuiltinID == Builtin::BIscanf) {
1354 const auto *FormatExpr =
1357 StringRef FormatStrRef;
1362 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1363 unsigned SourceSize) {
1364 DiagID = diag::warn_fortify_scanf_overflow;
1365 unsigned Index = ArgIndex + DataIndex;
1366 std::string FunctionName = Checker.getFunctionName();
1368 PDiag(DiagID) << FunctionName << (Index + 1)
1369 << DestSize << SourceSize);
1372 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1373 return Checker.ComputeSizeArgument(Index + DataIndex);
1375 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1376 const char *FormatBytes = FormatStrRef.data();
1387 case Builtin::BIsprintf:
1388 case Builtin::BI__builtin___sprintf_chk: {
1389 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1392 StringRef FormatStrRef;
1395 EstimateSizeFormatHandler H(FormatStrRef);
1396 const char *FormatBytes = FormatStrRef.data();
1398 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1399 Context.getTargetInfo(),
false)) {
1400 DiagID = H.isKernelCompatible()
1401 ? diag::warn_format_overflow
1402 : diag::warn_format_overflow_non_kprintf;
1403 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1404 .extOrTrunc(SizeTypeWidth);
1405 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1406 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1408 DestinationSize = Checker.ComputeSizeArgument(0);
1415 case Builtin::BI__builtin___memcpy_chk:
1416 case Builtin::BI__builtin___memmove_chk:
1417 case Builtin::BI__builtin___memset_chk:
1418 case Builtin::BI__builtin___strlcat_chk:
1419 case Builtin::BI__builtin___strlcpy_chk:
1420 case Builtin::BI__builtin___strncat_chk:
1421 case Builtin::BI__builtin___strncpy_chk:
1422 case Builtin::BI__builtin___stpncpy_chk:
1423 case Builtin::BI__builtin___memccpy_chk:
1424 case Builtin::BI__builtin___mempcpy_chk: {
1425 DiagID = diag::warn_builtin_chk_overflow;
1427 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1429 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1431 if (BuiltinID == Builtin::BI__builtin___memcpy_chk ||
1432 BuiltinID == Builtin::BI__builtin___memmove_chk ||
1433 BuiltinID == Builtin::BI__builtin___mempcpy_chk) {
1434 Checker.checkSourceOverread(1, 2);
1439 case Builtin::BI__builtin___snprintf_chk:
1440 case Builtin::BI__builtin___vsnprintf_chk: {
1441 DiagID = diag::warn_builtin_chk_overflow;
1442 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1443 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(3);
1447 case Builtin::BIstrncat:
1448 case Builtin::BI__builtin_strncat:
1449 case Builtin::BIstrncpy:
1450 case Builtin::BI__builtin_strncpy:
1451 case Builtin::BIstpncpy:
1452 case Builtin::BI__builtin_stpncpy:
1453 case Builtin::BIstrlcat:
1454 case Builtin::BI__builtin_strlcat:
1455 case Builtin::BIstrlcpy:
1456 case Builtin::BI__builtin_strlcpy: {
1462 DiagID = diag::warn_fortify_source_size_mismatch;
1464 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1465 DestinationSize = Checker.ComputeSizeArgument(0);
1469 case Builtin::BIrecv:
1470 case Builtin::BIrecvfrom: {
1471 unsigned ExpectedArgs = BuiltinID == Builtin::BIrecv ? 4 : 6;
1476 DiagID = diag::warn_fortify_source_size_mismatch;
1477 SourceSize = Checker.ComputeExplicitObjectSizeArgument(2);
1478 DestinationSize = Checker.ComputeSizeArgument(1);
1482 case Builtin::BIbzero:
1483 case Builtin::BI__builtin_bzero:
1484 case Builtin::BImemcpy:
1485 case Builtin::BI__builtin_memcpy:
1486 case Builtin::BImemmove:
1487 case Builtin::BI__builtin_memmove:
1488 case Builtin::BImemset:
1489 case Builtin::BI__builtin_memset:
1490 case Builtin::BImempcpy:
1491 case Builtin::BI__builtin_mempcpy: {
1492 DiagID = diag::warn_fortify_source_overflow;
1494 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1495 DestinationSize = Checker.ComputeSizeArgument(0);
1498 if (BuiltinID != Builtin::BImemset &&
1499 BuiltinID != Builtin::BI__builtin_memset &&
1500 BuiltinID != Builtin::BIbzero &&
1501 BuiltinID != Builtin::BI__builtin_bzero) {
1502 Checker.checkSourceOverread(1, 2);
1506 case Builtin::BIbcopy:
1507 case Builtin::BI__builtin_bcopy: {
1508 DiagID = diag::warn_fortify_source_overflow;
1510 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1511 DestinationSize = Checker.ComputeSizeArgument(1);
1512 Checker.checkSourceOverread(0, 2);
1517 case Builtin::BImemchr:
1518 case Builtin::BI__builtin_memchr: {
1519 Checker.checkSourceOverread(0, 2);
1525 case Builtin::BImemcmp:
1526 case Builtin::BI__builtin_memcmp:
1527 case Builtin::BIbcmp:
1528 case Builtin::BI__builtin_bcmp: {
1529 Checker.checkSourceOverread(0, 2);
1530 Checker.checkSourceOverread(1, 2);
1533 case Builtin::BIsnprintf:
1534 case Builtin::BI__builtin_snprintf:
1535 case Builtin::BIvsnprintf:
1536 case Builtin::BI__builtin_vsnprintf: {
1537 DiagID = diag::warn_fortify_source_size_mismatch;
1538 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1540 StringRef FormatStrRef;
1544 EstimateSizeFormatHandler H(FormatStrRef);
1545 const char *FormatBytes = FormatStrRef.data();
1547 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1548 Context.getTargetInfo(),
false)) {
1549 llvm::APSInt FormatSize =
1550 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1551 .extOrTrunc(SizeTypeWidth);
1552 if (FormatSize > *SourceSize && *SourceSize != 0) {
1553 unsigned TruncationDiagID =
1554 H.isKernelCompatible() ? diag::warn_format_truncation
1555 : diag::warn_format_truncation_non_kprintf;
1556 SmallString<16> SpecifiedSizeStr;
1557 SmallString<16> FormatSizeStr;
1558 SourceSize->toString(SpecifiedSizeStr, 10);
1559 FormatSize.toString(FormatSizeStr, 10);
1561 PDiag(TruncationDiagID)
1562 << Checker.getFunctionName()
1563 << SpecifiedSizeStr << FormatSizeStr);
1567 DestinationSize = Checker.ComputeSizeArgument(0);
1571 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1575 if (!SourceSize || !DestinationSize ||
1576 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1579 std::string FunctionName = Checker.getFunctionName();
1581 SmallString<16> DestinationStr;
1582 SmallString<16> SourceStr;
1583 DestinationSize->toString(DestinationStr, 10);
1584 SourceSize->toString(SourceStr, 10);
1587 << FunctionName << DestinationStr << SourceStr);
1607 Expr *Arg = TheCall->
getArg(0);
1615 llvm::APInt RawValue =
R.Val.getInt();
1616 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1617 llvm::APInt
Extra = RawValue & ~Mask;
1620 SmallString<16> ExtraStr;
1621 Extra.toString(ExtraStr, 8,
false);
1638 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1641 << DRE->getDecl()->getIdentifier();
1653 "__builtin_alloca has invalid address space");
1679enum PointerAuthOpKind {
1695 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1726 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1729 llvm::raw_svector_ostream Str(
Value);
1738 Result = KeyValue->getZExtValue();
1757 bool IsAddrDiscArg =
false;
1762 IsAddrDiscArg =
true;
1771 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1772 <<
Result->getExtValue();
1774 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1780 IntVal =
Result->getZExtValue();
1784static std::pair<const ValueDecl *, CharUnits>
1791 const auto *BaseDecl =
1796 return {BaseDecl,
Result.Val.getLValueOffset()};
1800 bool RequireConstant =
false) {
1808 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1809 return OpKind != PAO_BlendInteger;
1811 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1812 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1813 OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
1822 }
else if (AllowsInteger(OpKind) &&
1829 <<
unsigned(OpKind == PAO_Discriminator ? 1
1830 : OpKind == PAO_BlendPointer ? 2
1831 : OpKind == PAO_BlendInteger ? 3
1832 : OpKind == PAO_BlendPC ? 4
1834 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1844 if (!RequireConstant) {
1846 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1849 ? diag::warn_ptrauth_sign_null_pointer
1850 : diag::warn_ptrauth_auth_null_pointer)
1860 if (OpKind == PAO_Sign) {
1878 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1883 assert(OpKind == PAO_Discriminator);
1889 if (
Call->getBuiltinCallee() ==
1890 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1905 assert(
Pointer->getType()->isPointerType());
1917 assert(
Integer->getType()->isIntegerType());
1923 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1936 Call->setType(
Call->getArgs()[0]->getType());
1967 PointerAuthOpKind OpKind,
1968 bool RequireConstant) {
1979 Call->setType(
Call->getArgs()[0]->getType());
1995 Call->setType(
Call->getArgs()[0]->getType());
2016 unsigned OldKey = 0;
2019 if (OldKey !=
static_cast<unsigned>(AK::ASIA) &&
2020 OldKey !=
static_cast<unsigned>(AK::ASIB)) {
2021 S.
Diag(
Call->getArgs()[1]->getExprLoc(),
2022 diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
2023 << OldKey <<
Call->getArgs()[1]->getSourceRange();
2028 Call->setType(
Call->getArgs()[0]->getType());
2037 const Expr *AddendExpr =
Call->getArg(5);
2039 if (!AddendIsConstInt) {
2040 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
2054 Call->setType(
Call->getArgs()[0]->getType());
2063 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
2066 const auto *Literal = dyn_cast<StringLiteral>(Arg);
2067 if (!Literal || Literal->getCharByteWidth() != 1) {
2083 Call->setArg(0, FirstValue.
get());
2089 if (!FirstArgRecord) {
2090 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2091 << 0 << FirstArgType;
2096 diag::err_get_vtable_pointer_requires_complete_type)) {
2101 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2102 << 1 << FirstArgRecord;
2106 Call->setType(ReturnType);
2131 auto DiagSelect = [&]() -> std::optional<unsigned> {
2138 return std::optional<unsigned>{};
2153 diag::err_incomplete_type))
2157 "Unhandled non-object pointer case");
2185 if (PT->getPointeeType()->isFunctionType()) {
2187 diag::err_builtin_is_within_lifetime_invalid_arg)
2193 if (PT->getPointeeType()->isVariableArrayType()) {
2195 << 1 <<
"__builtin_is_within_lifetime";
2200 diag::err_builtin_is_within_lifetime_invalid_arg)
2214 diag::err_builtin_trivially_relocate_invalid_arg_type)
2221 diag::err_incomplete_type))
2225 T->isIncompleteArrayType()) {
2227 diag::err_builtin_trivially_relocate_invalid_arg_type)
2228 << (
T.isConstQualified() ? 1 : 2);
2237 diag::err_builtin_trivially_relocate_invalid_arg_type)
2244 if (Size.isInvalid())
2248 if (Size.isInvalid())
2250 SizeExpr = Size.get();
2251 TheCall->
setArg(2, SizeExpr);
2261 llvm::Triple::ObjectFormatType CurObjFormat =
2263 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2276 llvm::Triple::ArchType CurArch =
2278 if (llvm::is_contained(SupportedArchs, CurArch))
2288bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2295 case llvm::Triple::arm:
2296 case llvm::Triple::armeb:
2297 case llvm::Triple::thumb:
2298 case llvm::Triple::thumbeb:
2300 case llvm::Triple::aarch64:
2301 case llvm::Triple::aarch64_32:
2302 case llvm::Triple::aarch64_be:
2304 case llvm::Triple::bpfeb:
2305 case llvm::Triple::bpfel:
2307 case llvm::Triple::dxil:
2309 case llvm::Triple::hexagon:
2311 case llvm::Triple::mips:
2312 case llvm::Triple::mipsel:
2313 case llvm::Triple::mips64:
2314 case llvm::Triple::mips64el:
2316 case llvm::Triple::spirv:
2317 case llvm::Triple::spirv32:
2318 case llvm::Triple::spirv64:
2319 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2322 case llvm::Triple::systemz:
2324 case llvm::Triple::x86:
2325 case llvm::Triple::x86_64:
2327 case llvm::Triple::ppc:
2328 case llvm::Triple::ppcle:
2329 case llvm::Triple::ppc64:
2330 case llvm::Triple::ppc64le:
2332 case llvm::Triple::amdgpu:
2334 case llvm::Triple::riscv32:
2335 case llvm::Triple::riscv64:
2336 case llvm::Triple::riscv32be:
2337 case llvm::Triple::riscv64be:
2339 case llvm::Triple::loongarch32:
2340 case llvm::Triple::loongarch64:
2343 case llvm::Triple::wasm32:
2344 case llvm::Triple::wasm64:
2346 case llvm::Triple::nvptx:
2347 case llvm::Triple::nvptx64:
2353 return T->isDependentType() ||
2354 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2369 switch (ArgTyRestr) {
2373 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2374 << ArgOrdinal << 2 << 1 << 1
2381 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2382 << ArgOrdinal << 5 << 0
2388 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2389 << ArgOrdinal << 5 << 1
2395 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2409 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2410 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2411 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2412 "Expecting __builtin_cpu_...");
2414 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2416 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2417 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2418 (!IsCPUSupports && TInfo->supportsCpuIs()));
2420 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2427 ? diag::err_builtin_aix_os_unsupported
2428 : diag::err_builtin_target_unsupported)
2434 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2472 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2473 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2474 BT->getNumBits() != 1) {
2476 << ArgTy << BT->getNumBits();
2552 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2555 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2564 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2565 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2585 TheCall->
setArg(0, Arg0);
2602 TheCall->
setArg(1, Arg1);
2608 << 2 << 1 << 4 << 0 << Arg1Ty;
2622 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2624 << (OnlyUnsigned ? 3 : 1)
2632 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2635 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2640 return emitError(S, Loc,
T);
2645 return emitError(S, Loc,
T);
2651 return emitError(S, Loc,
T);
2656 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2661 return emitError(S, Loc,
T);
2666 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2672 llvm_unreachable(
"conversion functions are permitted");
2691 TheCall->
setArg(0, Arg0);
2705 TheCall->
setArg(1, Arg1);
2716 unsigned Pos,
bool AllowConst,
2720 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2725 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2726 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2727 << Pos <<
"scalar pointer";
2736 diag::err_typecheck_convert_incompatible)
2745 bool TypeDependent =
false;
2746 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2774 Builtin::BI__builtin_masked_load))
2788 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2811 Builtin::BI__builtin_masked_store))
2819 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2830 << MaskTy << ValTy);
2834 PtrTy->getPointeeType().getUnqualifiedType()))
2836 diag::err_vec_builtin_incompatible_vector)
2865 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2878 << MaskTy << IdxTy);
2887 diag::err_vec_masked_load_store_ptr)
2916 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2931 << MaskTy << IdxTy);
2937 << MaskTy << ValTy);
2940 PtrTy->getPointeeType().getUnqualifiedType()))
2942 diag::err_vec_builtin_incompatible_vector)
2956 if (Args.size() == 0) {
2958 diag::err_typecheck_call_too_few_args_at_least)
2964 QualType FuncT = Args[0]->getType();
2967 if (Args.size() < 2) {
2969 diag::err_typecheck_call_too_few_args_at_least)
2975 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2976 QualType ObjectT = Args[1]->getType();
2978 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
3027 tok::periodstar, ObjectArg.
get(), Args[0]);
3031 if (MPT->isMemberDataPointer())
3035 auto *MemCall =
new (S.
Context)
3059 return TyA->getElementType();
3066Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
3071 unsigned ICEArguments = 0;
3073 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
3078 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
3080 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
3085 if (ArgNo < TheCall->getNumArgs() &&
3088 ICEArguments &= ~(1 << ArgNo);
3092 switch (BuiltinID) {
3093 case Builtin::BI__builtin___get_unsafe_stack_start:
3094 case Builtin::BI__builtin___get_unsafe_stack_bottom:
3096 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3097 <<
"__safestack_get_unsafe_stack_bottom";
3099 case Builtin::BI__builtin___get_unsafe_stack_top:
3101 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3102 <<
"__safestack_get_unsafe_stack_top";
3104 case Builtin::BI__builtin___get_unsafe_stack_ptr:
3106 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3107 <<
"__safestack_get_unsafe_stack_ptr";
3109 case Builtin::BI__builtin_cpu_supports:
3110 case Builtin::BI__builtin_cpu_is:
3112 Context.getAuxTargetInfo(), BuiltinID))
3115 case Builtin::BI__builtin_cpu_init:
3116 if (!
Context.getTargetInfo().supportsCpuInit()) {
3122 case Builtin::BI__builtin___CFStringMakeConstantString:
3126 *
this, BuiltinID, TheCall,
3127 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
3130 "Wrong # arguments to builtin CFStringMakeConstantString");
3131 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3134 case Builtin::BI__builtin_ms_va_start:
3135 case Builtin::BI__builtin_zos_va_start:
3136 case Builtin::BI__builtin_stdarg_start:
3137 case Builtin::BI__builtin_va_start:
3138 case Builtin::BI__builtin_c23_va_start:
3139 if (BuiltinVAStart(BuiltinID, TheCall))
3142 case Builtin::BI__va_start: {
3143 switch (
Context.getTargetInfo().getTriple().getArch()) {
3144 case llvm::Triple::aarch64:
3145 case llvm::Triple::arm:
3146 case llvm::Triple::thumb:
3147 if (BuiltinVAStartARMMicrosoft(TheCall))
3151 if (BuiltinVAStart(BuiltinID, TheCall))
3159 case Builtin::BI_interlockedbittestandset_acq:
3160 case Builtin::BI_interlockedbittestandset_rel:
3161 case Builtin::BI_interlockedbittestandset_nf:
3162 case Builtin::BI_interlockedbittestandreset_acq:
3163 case Builtin::BI_interlockedbittestandreset_rel:
3164 case Builtin::BI_interlockedbittestandreset_nf:
3167 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3172 case Builtin::BI_bittest64:
3173 case Builtin::BI_bittestandcomplement64:
3174 case Builtin::BI_bittestandreset64:
3175 case Builtin::BI_bittestandset64:
3176 case Builtin::BI_interlockedbittestandreset64:
3177 case Builtin::BI_interlockedbittestandset64:
3180 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3181 llvm::Triple::aarch64, llvm::Triple::amdgpu}))
3186 case Builtin::BI_interlockedbittestandreset64_acq:
3187 case Builtin::BI_interlockedbittestandreset64_rel:
3188 case Builtin::BI_interlockedbittestandreset64_nf:
3189 case Builtin::BI_interlockedbittestandset64_acq:
3190 case Builtin::BI_interlockedbittestandset64_rel:
3191 case Builtin::BI_interlockedbittestandset64_nf:
3196 case Builtin::BI__builtin_set_flt_rounds:
3199 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3200 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgpu,
3201 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3202 llvm::Triple::ppc64le}))
3206 case Builtin::BI__builtin_isgreater:
3207 case Builtin::BI__builtin_isgreaterequal:
3208 case Builtin::BI__builtin_isless:
3209 case Builtin::BI__builtin_islessequal:
3210 case Builtin::BI__builtin_islessgreater:
3211 case Builtin::BI__builtin_isunordered:
3212 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3215 case Builtin::BI__builtin_fpclassify:
3216 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3219 case Builtin::BI__builtin_isfpclass:
3220 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3223 case Builtin::BI__builtin_isfinite:
3224 case Builtin::BI__builtin_isinf:
3225 case Builtin::BI__builtin_isinf_sign:
3226 case Builtin::BI__builtin_isnan:
3227 case Builtin::BI__builtin_issignaling:
3228 case Builtin::BI__builtin_isnormal:
3229 case Builtin::BI__builtin_issubnormal:
3230 case Builtin::BI__builtin_iszero:
3231 case Builtin::BI__builtin_signbit:
3232 case Builtin::BI__builtin_signbitf:
3233 case Builtin::BI__builtin_signbitl:
3234 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3237 case Builtin::BI__builtin_shufflevector:
3241 case Builtin::BI__builtin_masked_load:
3242 case Builtin::BI__builtin_masked_expand_load:
3244 case Builtin::BI__builtin_masked_store:
3245 case Builtin::BI__builtin_masked_compress_store:
3247 case Builtin::BI__builtin_masked_gather:
3249 case Builtin::BI__builtin_masked_scatter:
3251 case Builtin::BI__builtin_invoke:
3253 case Builtin::BI__builtin_prefetch:
3254 if (BuiltinPrefetch(TheCall))
3257 case Builtin::BI__builtin_alloca_with_align:
3258 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3259 if (BuiltinAllocaWithAlign(TheCall))
3262 case Builtin::BI__builtin_alloca:
3263 case Builtin::BI__builtin_alloca_uninitialized:
3270 case Builtin::BI__builtin_infer_alloc_token:
3274 case Builtin::BI__arithmetic_fence:
3275 if (BuiltinArithmeticFence(TheCall))
3278 case Builtin::BI__assume:
3279 case Builtin::BI__builtin_assume:
3280 if (BuiltinAssume(TheCall))
3283 case Builtin::BI__builtin_assume_aligned:
3284 if (BuiltinAssumeAligned(TheCall))
3287 case Builtin::BI__builtin_dynamic_object_size:
3288 case Builtin::BI__builtin_object_size:
3292 case Builtin::BI__builtin_longjmp:
3293 if (BuiltinLongjmp(TheCall))
3296 case Builtin::BI__builtin_setjmp:
3297 if (BuiltinSetjmp(TheCall))
3300 case Builtin::BI__builtin_complex:
3301 if (BuiltinComplex(TheCall))
3304 case Builtin::BI__builtin_classify_type:
3305 case Builtin::BI__builtin_constant_p: {
3314 case Builtin::BI__builtin_launder:
3316 case Builtin::BI__builtin_is_within_lifetime:
3318 case Builtin::BI__builtin_trivially_relocate:
3320 case Builtin::BI__builtin_clear_padding: {
3324 const Expr *PtrArg = TheCall->
getArg(0);
3325 const QualType PtrArgType = PtrArg->
getType();
3328 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3339 diag::err_typecheck_decl_incomplete_type))
3345 auto IsAddrOfDeclExpr = [&]() {
3347 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3348 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3352 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3353 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3357 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3358 if (!VarDecl || VarDecl->getType()->isReferenceType())
3363 QualType VarQType = VarDecl->getType();
3365 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3370 && !IsAddrOfDeclExpr()) {
3371 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3378 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3385 case Builtin::BI__sync_fetch_and_add:
3386 case Builtin::BI__sync_fetch_and_add_1:
3387 case Builtin::BI__sync_fetch_and_add_2:
3388 case Builtin::BI__sync_fetch_and_add_4:
3389 case Builtin::BI__sync_fetch_and_add_8:
3390 case Builtin::BI__sync_fetch_and_add_16:
3391 case Builtin::BI__sync_fetch_and_sub:
3392 case Builtin::BI__sync_fetch_and_sub_1:
3393 case Builtin::BI__sync_fetch_and_sub_2:
3394 case Builtin::BI__sync_fetch_and_sub_4:
3395 case Builtin::BI__sync_fetch_and_sub_8:
3396 case Builtin::BI__sync_fetch_and_sub_16:
3397 case Builtin::BI__sync_fetch_and_or:
3398 case Builtin::BI__sync_fetch_and_or_1:
3399 case Builtin::BI__sync_fetch_and_or_2:
3400 case Builtin::BI__sync_fetch_and_or_4:
3401 case Builtin::BI__sync_fetch_and_or_8:
3402 case Builtin::BI__sync_fetch_and_or_16:
3403 case Builtin::BI__sync_fetch_and_and:
3404 case Builtin::BI__sync_fetch_and_and_1:
3405 case Builtin::BI__sync_fetch_and_and_2:
3406 case Builtin::BI__sync_fetch_and_and_4:
3407 case Builtin::BI__sync_fetch_and_and_8:
3408 case Builtin::BI__sync_fetch_and_and_16:
3409 case Builtin::BI__sync_fetch_and_xor:
3410 case Builtin::BI__sync_fetch_and_xor_1:
3411 case Builtin::BI__sync_fetch_and_xor_2:
3412 case Builtin::BI__sync_fetch_and_xor_4:
3413 case Builtin::BI__sync_fetch_and_xor_8:
3414 case Builtin::BI__sync_fetch_and_xor_16:
3415 case Builtin::BI__sync_fetch_and_nand:
3416 case Builtin::BI__sync_fetch_and_nand_1:
3417 case Builtin::BI__sync_fetch_and_nand_2:
3418 case Builtin::BI__sync_fetch_and_nand_4:
3419 case Builtin::BI__sync_fetch_and_nand_8:
3420 case Builtin::BI__sync_fetch_and_nand_16:
3421 case Builtin::BI__sync_add_and_fetch:
3422 case Builtin::BI__sync_add_and_fetch_1:
3423 case Builtin::BI__sync_add_and_fetch_2:
3424 case Builtin::BI__sync_add_and_fetch_4:
3425 case Builtin::BI__sync_add_and_fetch_8:
3426 case Builtin::BI__sync_add_and_fetch_16:
3427 case Builtin::BI__sync_sub_and_fetch:
3428 case Builtin::BI__sync_sub_and_fetch_1:
3429 case Builtin::BI__sync_sub_and_fetch_2:
3430 case Builtin::BI__sync_sub_and_fetch_4:
3431 case Builtin::BI__sync_sub_and_fetch_8:
3432 case Builtin::BI__sync_sub_and_fetch_16:
3433 case Builtin::BI__sync_and_and_fetch:
3434 case Builtin::BI__sync_and_and_fetch_1:
3435 case Builtin::BI__sync_and_and_fetch_2:
3436 case Builtin::BI__sync_and_and_fetch_4:
3437 case Builtin::BI__sync_and_and_fetch_8:
3438 case Builtin::BI__sync_and_and_fetch_16:
3439 case Builtin::BI__sync_or_and_fetch:
3440 case Builtin::BI__sync_or_and_fetch_1:
3441 case Builtin::BI__sync_or_and_fetch_2:
3442 case Builtin::BI__sync_or_and_fetch_4:
3443 case Builtin::BI__sync_or_and_fetch_8:
3444 case Builtin::BI__sync_or_and_fetch_16:
3445 case Builtin::BI__sync_xor_and_fetch:
3446 case Builtin::BI__sync_xor_and_fetch_1:
3447 case Builtin::BI__sync_xor_and_fetch_2:
3448 case Builtin::BI__sync_xor_and_fetch_4:
3449 case Builtin::BI__sync_xor_and_fetch_8:
3450 case Builtin::BI__sync_xor_and_fetch_16:
3451 case Builtin::BI__sync_nand_and_fetch:
3452 case Builtin::BI__sync_nand_and_fetch_1:
3453 case Builtin::BI__sync_nand_and_fetch_2:
3454 case Builtin::BI__sync_nand_and_fetch_4:
3455 case Builtin::BI__sync_nand_and_fetch_8:
3456 case Builtin::BI__sync_nand_and_fetch_16:
3457 case Builtin::BI__sync_val_compare_and_swap:
3458 case Builtin::BI__sync_val_compare_and_swap_1:
3459 case Builtin::BI__sync_val_compare_and_swap_2:
3460 case Builtin::BI__sync_val_compare_and_swap_4:
3461 case Builtin::BI__sync_val_compare_and_swap_8:
3462 case Builtin::BI__sync_val_compare_and_swap_16:
3463 case Builtin::BI__sync_bool_compare_and_swap:
3464 case Builtin::BI__sync_bool_compare_and_swap_1:
3465 case Builtin::BI__sync_bool_compare_and_swap_2:
3466 case Builtin::BI__sync_bool_compare_and_swap_4:
3467 case Builtin::BI__sync_bool_compare_and_swap_8:
3468 case Builtin::BI__sync_bool_compare_and_swap_16:
3469 case Builtin::BI__sync_lock_test_and_set:
3470 case Builtin::BI__sync_lock_test_and_set_1:
3471 case Builtin::BI__sync_lock_test_and_set_2:
3472 case Builtin::BI__sync_lock_test_and_set_4:
3473 case Builtin::BI__sync_lock_test_and_set_8:
3474 case Builtin::BI__sync_lock_test_and_set_16:
3475 case Builtin::BI__sync_lock_release:
3476 case Builtin::BI__sync_lock_release_1:
3477 case Builtin::BI__sync_lock_release_2:
3478 case Builtin::BI__sync_lock_release_4:
3479 case Builtin::BI__sync_lock_release_8:
3480 case Builtin::BI__sync_lock_release_16:
3481 case Builtin::BI__sync_swap:
3482 case Builtin::BI__sync_swap_1:
3483 case Builtin::BI__sync_swap_2:
3484 case Builtin::BI__sync_swap_4:
3485 case Builtin::BI__sync_swap_8:
3486 case Builtin::BI__sync_swap_16:
3487 return BuiltinAtomicOverloaded(TheCallResult);
3488 case Builtin::BI__sync_synchronize:
3492 case Builtin::BI__builtin_nontemporal_load:
3493 case Builtin::BI__builtin_nontemporal_store:
3494 return BuiltinNontemporalOverloaded(TheCallResult);
3495 case Builtin::BI__builtin_memcpy_inline: {
3496 clang::Expr *SizeOp = TheCall->
getArg(2);
3508 case Builtin::BI__builtin_memset_inline: {
3509 clang::Expr *SizeOp = TheCall->
getArg(2);
3519#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3520 case Builtin::BI##ID: \
3521 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3522#include "clang/Basic/Builtins.inc"
3523 case Builtin::BI__annotation: {
3524 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3525 if (!TT.isOSWindows() && !TT.isUEFI()) {
3534 case Builtin::BI__builtin_annotation:
3538 case Builtin::BI__builtin_addressof:
3542 case Builtin::BI__builtin_function_start:
3546 case Builtin::BI__builtin_is_aligned:
3547 case Builtin::BI__builtin_align_up:
3548 case Builtin::BI__builtin_align_down:
3552 case Builtin::BI__builtin_add_overflow:
3553 case Builtin::BI__builtin_sub_overflow:
3554 case Builtin::BI__builtin_mul_overflow:
3558 case Builtin::BI__builtin_operator_new:
3559 case Builtin::BI__builtin_operator_delete: {
3560 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3562 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3565 case Builtin::BI__builtin_dump_struct:
3567 case Builtin::BI__builtin_expect_with_probability: {
3572 const Expr *ProbArg = TheCall->
getArg(2);
3573 SmallVector<PartialDiagnosticAt, 8> Notes;
3574 Expr::EvalResult Eval;
3578 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3585 bool LoseInfo =
false;
3586 Probability.convert(llvm::APFloat::IEEEdouble(),
3587 llvm::RoundingMode::Dynamic, &LoseInfo);
3588 if (!(Probability >= llvm::APFloat(0.0) &&
3589 Probability <= llvm::APFloat(1.0))) {
3596 case Builtin::BI__builtin_preserve_access_index:
3600 case Builtin::BI__builtin_call_with_static_chain:
3604 case Builtin::BI__exception_code:
3605 case Builtin::BI_exception_code:
3607 diag::err_seh___except_block))
3610 case Builtin::BI__exception_info:
3611 case Builtin::BI_exception_info:
3613 diag::err_seh___except_filter))
3616 case Builtin::BI__GetExceptionInfo:
3628 case Builtin::BIaddressof:
3629 case Builtin::BI__addressof:
3630 case Builtin::BIforward:
3631 case Builtin::BIforward_like:
3632 case Builtin::BImove:
3633 case Builtin::BImove_if_noexcept:
3634 case Builtin::BIas_const: {
3642 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3643 BuiltinID == Builtin::BI__addressof;
3645 (ReturnsPointer ?
Result->isAnyPointerType()
3646 :
Result->isReferenceType()) &&
3649 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3655 case Builtin::BI__builtin_ptrauth_strip:
3657 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3659 case Builtin::BI__builtin_ptrauth_sign_constant:
3662 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3665 case Builtin::BI__builtin_ptrauth_auth:
3668 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3670 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3672 case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
3674 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3676 case Builtin::BI__builtin_ptrauth_string_discriminator:
3679 case Builtin::BI__builtin_get_vtable_pointer:
3683 case Builtin::BIread_pipe:
3684 case Builtin::BIwrite_pipe:
3687 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3690 case Builtin::BIreserve_read_pipe:
3691 case Builtin::BIreserve_write_pipe:
3692 case Builtin::BIwork_group_reserve_read_pipe:
3693 case Builtin::BIwork_group_reserve_write_pipe:
3694 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3697 case Builtin::BIsub_group_reserve_read_pipe:
3698 case Builtin::BIsub_group_reserve_write_pipe:
3699 if (
OpenCL().checkSubgroupExt(TheCall) ||
3700 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3703 case Builtin::BIcommit_read_pipe:
3704 case Builtin::BIcommit_write_pipe:
3705 case Builtin::BIwork_group_commit_read_pipe:
3706 case Builtin::BIwork_group_commit_write_pipe:
3707 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3710 case Builtin::BIsub_group_commit_read_pipe:
3711 case Builtin::BIsub_group_commit_write_pipe:
3712 if (
OpenCL().checkSubgroupExt(TheCall) ||
3713 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3716 case Builtin::BIget_pipe_num_packets:
3717 case Builtin::BIget_pipe_max_packets:
3718 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3721 case Builtin::BIto_global:
3722 case Builtin::BIto_local:
3723 case Builtin::BIto_private:
3724 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3728 case Builtin::BIenqueue_kernel:
3729 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3732 case Builtin::BIget_kernel_work_group_size:
3733 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3734 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3737 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3738 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3739 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3742 case Builtin::BI__builtin_os_log_format:
3743 Cleanup.setExprNeedsCleanups(
true);
3745 case Builtin::BI__builtin_os_log_format_buffer_size:
3746 if (BuiltinOSLogFormat(TheCall))
3749 case Builtin::BI__builtin_frame_address:
3750 case Builtin::BI__builtin_return_address: {
3759 Result.Val.getInt() != 0)
3761 << ((BuiltinID == Builtin::BI__builtin_return_address)
3762 ?
"__builtin_return_address"
3763 :
"__builtin_frame_address")
3768 case Builtin::BI__builtin_nondeterministic_value: {
3769 if (BuiltinNonDeterministicValue(TheCall))
3776 case Builtin::BI__builtin_elementwise_abs:
3784 case Builtin::BI__builtin_elementwise_acos:
3785 case Builtin::BI__builtin_elementwise_asin:
3786 case Builtin::BI__builtin_elementwise_atan:
3787 case Builtin::BI__builtin_elementwise_ceil:
3788 case Builtin::BI__builtin_elementwise_cos:
3789 case Builtin::BI__builtin_elementwise_cosh:
3790 case Builtin::BI__builtin_elementwise_exp:
3791 case Builtin::BI__builtin_elementwise_exp2:
3792 case Builtin::BI__builtin_elementwise_exp10:
3793 case Builtin::BI__builtin_elementwise_floor:
3794 case Builtin::BI__builtin_elementwise_log:
3795 case Builtin::BI__builtin_elementwise_log2:
3796 case Builtin::BI__builtin_elementwise_log10:
3797 case Builtin::BI__builtin_elementwise_roundeven:
3798 case Builtin::BI__builtin_elementwise_round:
3799 case Builtin::BI__builtin_elementwise_rint:
3800 case Builtin::BI__builtin_elementwise_nearbyint:
3801 case Builtin::BI__builtin_elementwise_sin:
3802 case Builtin::BI__builtin_elementwise_sinh:
3803 case Builtin::BI__builtin_elementwise_sqrt:
3804 case Builtin::BI__builtin_elementwise_tan:
3805 case Builtin::BI__builtin_elementwise_tanh:
3806 case Builtin::BI__builtin_elementwise_trunc:
3807 case Builtin::BI__builtin_elementwise_canonicalize:
3812 case Builtin::BI__builtin_elementwise_fma:
3817 case Builtin::BI__builtin_elementwise_ldexp: {
3839 const auto *Vec0 = TyA->
getAs<VectorType>();
3840 const auto *Vec1 = TyExp->
getAs<VectorType>();
3841 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3843 if (Arg0Length != Arg1Length) {
3845 diag::err_typecheck_vector_lengths_not_equal)
3859 case Builtin::BI__builtin_elementwise_minnum:
3860 case Builtin::BI__builtin_elementwise_maxnum:
3861 case Builtin::BI__builtin_elementwise_minimum:
3862 case Builtin::BI__builtin_elementwise_maximum:
3863 case Builtin::BI__builtin_elementwise_minimumnum:
3864 case Builtin::BI__builtin_elementwise_maximumnum:
3865 case Builtin::BI__builtin_elementwise_atan2:
3866 case Builtin::BI__builtin_elementwise_fmod:
3867 case Builtin::BI__builtin_elementwise_pow:
3868 if (BuiltinElementwiseMath(TheCall,
3874 case Builtin::BI__builtin_elementwise_add_sat:
3875 case Builtin::BI__builtin_elementwise_sub_sat:
3876 case Builtin::BI__builtin_elementwise_clmul:
3877 case Builtin::BI__builtin_elementwise_pext:
3878 case Builtin::BI__builtin_elementwise_pdep:
3879 if (BuiltinElementwiseMath(TheCall,
3883 case Builtin::BI__builtin_elementwise_fshl:
3884 case Builtin::BI__builtin_elementwise_fshr:
3889 case Builtin::BI__builtin_elementwise_min:
3890 case Builtin::BI__builtin_elementwise_max: {
3891 if (BuiltinElementwiseMath(TheCall))
3893 Expr *Arg0 = TheCall->
getArg(0);
3894 Expr *Arg1 = TheCall->
getArg(1);
3895 QualType Ty0 = Arg0->
getType();
3896 QualType Ty1 = Arg1->
getType();
3897 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3898 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3901 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3902 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3903 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3906 case Builtin::BI__builtin_elementwise_popcount:
3907 case Builtin::BI__builtin_elementwise_bitreverse:
3912 case Builtin::BI__builtin_elementwise_copysign: {
3921 QualType MagnitudeTy = Magnitude.
get()->
getType();
3934 diag::err_typecheck_call_different_arg_types)
3935 << MagnitudeTy << SignTy;
3943 case Builtin::BI__builtin_elementwise_clzg:
3944 case Builtin::BI__builtin_elementwise_ctzg:
3952 }
else if (BuiltinElementwiseMath(
3956 case Builtin::BI__builtin_reduce_max:
3957 case Builtin::BI__builtin_reduce_min: {
3958 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3961 const Expr *Arg = TheCall->
getArg(0);
3966 ElTy = TyA->getElementType();
3970 if (ElTy.isNull()) {
3980 case Builtin::BI__builtin_reduce_maximum:
3981 case Builtin::BI__builtin_reduce_minimum: {
3982 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3985 const Expr *Arg = TheCall->
getArg(0);
3990 ElTy = TyA->getElementType();
3994 if (ElTy.isNull() || !ElTy->isFloatingType()) {
4007 case Builtin::BI__builtin_reduce_add:
4008 case Builtin::BI__builtin_reduce_mul:
4009 case Builtin::BI__builtin_reduce_xor:
4010 case Builtin::BI__builtin_reduce_or:
4011 case Builtin::BI__builtin_reduce_and: {
4012 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4015 const Expr *Arg = TheCall->
getArg(0);
4029 case Builtin::BI__builtin_reduce_assoc_fadd:
4030 case Builtin::BI__builtin_reduce_in_order_fadd: {
4032 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
4057 diag::err_builtin_invalid_arg_type)
4069 case Builtin::BI__builtin_matrix_transpose:
4070 return BuiltinMatrixTranspose(TheCall, TheCallResult);
4072 case Builtin::BI__builtin_matrix_column_major_load:
4073 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
4075 case Builtin::BI__builtin_matrix_column_major_store:
4076 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
4078 case Builtin::BI__builtin_verbose_trap:
4083 case Builtin::BI__builtin_get_device_side_mangled_name: {
4084 auto Check = [](CallExpr *TheCall) {
4090 auto *D = DRE->getDecl();
4093 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
4094 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
4096 if (!Check(TheCall)) {
4098 diag::err_hip_invalid_args_builtin_mangled_name);
4103 case Builtin::BI__builtin_bswapg:
4107 case Builtin::BI__builtin_bitreverseg:
4111 case Builtin::BI__builtin_popcountg:
4115 case Builtin::BI__builtin_clzg:
4116 case Builtin::BI__builtin_ctzg:
4121 case Builtin::BI__builtin_stdc_rotate_left:
4122 case Builtin::BI__builtin_stdc_rotate_right:
4127 case Builtin::BI__builtin_stdc_memreverse8:
4128 case Builtin::BIstdc_memreverse8:
4129 case Builtin::BIstdc_memreverse8u8:
4130 case Builtin::BIstdc_memreverse8u16:
4131 case Builtin::BIstdc_memreverse8u32:
4132 case Builtin::BIstdc_memreverse8u64:
4133 if (
Context.getTargetInfo().getCharWidth() != 8) {
4140 case Builtin::BI__builtin_stdc_bit_floor:
4141 case Builtin::BI__builtin_stdc_bit_ceil:
4145 case Builtin::BI__builtin_stdc_has_single_bit:
4149 case Builtin::BI__builtin_stdc_leading_zeros:
4150 case Builtin::BI__builtin_stdc_leading_ones:
4151 case Builtin::BI__builtin_stdc_trailing_zeros:
4152 case Builtin::BI__builtin_stdc_trailing_ones:
4153 case Builtin::BI__builtin_stdc_first_leading_zero:
4154 case Builtin::BI__builtin_stdc_first_leading_one:
4155 case Builtin::BI__builtin_stdc_first_trailing_zero:
4156 case Builtin::BI__builtin_stdc_first_trailing_one:
4157 case Builtin::BI__builtin_stdc_count_zeros:
4158 case Builtin::BI__builtin_stdc_count_ones:
4159 case Builtin::BI__builtin_stdc_bit_width:
4164 case Builtin::BI__builtin_allow_runtime_check: {
4165 Expr *Arg = TheCall->
getArg(0);
4175 case Builtin::BI__builtin_allow_sanitize_check: {
4179 Expr *Arg = TheCall->
getArg(0);
4181 const StringLiteral *SanitizerName =
4183 if (!SanitizerName) {
4189 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4190 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4191 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4195 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4201 case Builtin::BI__builtin_counted_by_ref:
4202 if (BuiltinCountedByRef(TheCall))
4212 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4213 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4214 assert(
Context.getAuxTargetInfo() &&
4215 "Aux Target Builtin, but not an aux target?");
4217 if (CheckTSBuiltinFunctionCall(
4219 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4222 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4228 return TheCallResult;
4243 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4247 diag::err_argument_not_contiguous_bit_field)
4254 bool IsVariadic =
false;
4257 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4258 IsVariadic = BD->isVariadic();
4259 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4260 IsVariadic = OMD->isVariadic();
4267 bool HasImplicitThisParam,
bool IsVariadic,
4271 else if (IsVariadic)
4281 if (HasImplicitThisParam) {
4313 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4314 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4315 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4316 Expr = ILE->getInit(0);
4326 const Expr *ArgExpr,
4330 S.
PDiag(diag::warn_null_arg)
4336 if (
auto nullability =
type->getNullability())
4347 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4353 llvm::SmallBitVector NonNullArgs;
4359 for (
const auto *Arg : Args)
4366 unsigned IdxAST = Idx.getASTIndex();
4367 if (IdxAST >= Args.size())
4369 if (NonNullArgs.empty())
4370 NonNullArgs.resize(Args.size());
4371 NonNullArgs.set(IdxAST);
4380 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4385 unsigned ParamIndex = 0;
4387 I != E; ++I, ++ParamIndex) {
4390 if (NonNullArgs.empty())
4391 NonNullArgs.resize(Args.size());
4393 NonNullArgs.set(ParamIndex);
4400 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4405 type = blockType->getPointeeType();
4419 if (NonNullArgs.empty())
4420 NonNullArgs.resize(Args.size());
4422 NonNullArgs.set(Index);
4431 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4432 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4433 if (NonNullArgs[ArgIndex])
4439 StringRef ParamName,
QualType ArgTy,
4462 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4463 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4467 if (ArgAlign < ParamAlign)
4468 Diag(Loc, diag::warn_param_mismatched_alignment)
4470 << ParamName << (FDecl !=
nullptr) << FDecl;
4474 const Expr *ThisArg,
4476 if (!FD || Args.empty())
4478 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4479 if (Idx == LifetimeCaptureByAttr::Global ||
4480 Idx == LifetimeCaptureByAttr::Unknown)
4482 if (IsMemberFunction && Idx == 0)
4484 return Args[Idx - IsMemberFunction];
4486 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4491 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4492 for (
int CapturingParamIdx :
Attr->params()) {
4493 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4497 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4500 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4507 for (
const auto *A :
4509 HandleCaptureByAttr(A, I + IsMemberFunction);
4511 if (IsMemberFunction) {
4519 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4529 llvm::any_of(Args, [](
const Expr *E) {
4530 return E && E->isInstantiationDependent();
4535 llvm::SmallBitVector CheckedVarArgs;
4537 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4539 CheckedVarArgs.resize(Args.size());
4540 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4545 CheckedVarArgs.resize(Args.size());
4546 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4553 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4557 : isa_and_nonnull<FunctionDecl>(FDecl)
4559 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4563 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4565 if (
const Expr *Arg = Args[ArgIdx]) {
4566 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4573 if (FDecl || Proto) {
4578 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4579 CheckArgumentWithTypeTag(I, Args, Loc);
4585 if (!Proto && FDecl) {
4587 if (isa_and_nonnull<FunctionProtoType>(FT))
4593 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4595 bool IsScalableArg =
false;
4596 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4598 if (
const Expr *Arg = Args[ArgIdx]) {
4602 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4610 IsScalableArg =
true;
4612 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4621 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4622 llvm::StringMap<bool> CallerFeatureMap;
4623 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4624 if (!CallerFeatureMap.contains(
"sme"))
4625 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4626 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4627 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4636 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4638 (IsScalableArg || IsScalableRet)) {
4639 bool IsCalleeStreaming =
4641 bool IsCalleeStreamingCompatible =
4645 if (!IsCalleeStreamingCompatible &&
4649 unsigned VL = LO.VScaleMin * 128;
4650 unsigned SVL = LO.VScaleStreamingMin * 128;
4651 bool IsVLMismatch = VL && SVL && VL != SVL;
4653 auto EmitDiag = [&](
bool IsArg) {
4657 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4658 << IsArg << IsCalleeStreaming << SVL << VL;
4661 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4662 << IsArg << SVL << VL;
4664 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4681 bool CallerHasZAState =
false;
4682 bool CallerHasZT0State =
false;
4684 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4686 CallerHasZAState =
true;
4688 CallerHasZT0State =
true;
4692 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4694 CallerHasZT0State |=
4696 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4702 Diag(Loc, diag::err_sme_za_call_no_za_state);
4705 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4709 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4710 Diag(Loc, diag::note_sme_use_preserves_za);
4715 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4716 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4717 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4718 if (!Arg->isValueDependent()) {
4720 if (Arg->EvaluateAsInt(Align,
Context)) {
4721 const llvm::APSInt &I = Align.
Val.
getInt();
4722 if (!I.isPowerOf2())
4723 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4724 << Arg->getSourceRange();
4727 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4736 << diag::OffloadLang::SYCL;
4744 AutoT->getTypeConstraintConcept().getAsTemplateDecl()) {
4759 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4760 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4762 checkCall(FDecl, Proto,
nullptr, Args,
true,
4771 IsMemberOperatorCall;
4777 Expr *ImplicitThis =
nullptr;
4782 ImplicitThis = Args[0];
4785 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4796 ThisType =
Context.getPointerType(ThisType);
4802 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4820 CheckAbsoluteValueFunction(TheCall, FDecl);
4821 CheckMaxUnsignedZero(TheCall, FDecl);
4822 CheckInfNaNFunction(TheCall, FDecl);
4833 case Builtin::BIstrlcpy:
4834 case Builtin::BIstrlcat:
4835 CheckStrlcpycatArguments(TheCall, FnInfo);
4837 case Builtin::BIstrncat:
4838 CheckStrncatArguments(TheCall, FnInfo);
4840 case Builtin::BIfree:
4841 CheckFreeArguments(TheCall);
4844 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4853 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4854 Ty =
V->getType().getNonReferenceType();
4855 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4856 Ty = F->getType().getNonReferenceType();
4893 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4896 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4898 case AtomicExpr::AO__c11_atomic_init:
4899 case AtomicExpr::AO__opencl_atomic_init:
4900 llvm_unreachable(
"There is no ordering argument for an init");
4902 case AtomicExpr::AO__c11_atomic_load:
4903 case AtomicExpr::AO__opencl_atomic_load:
4904 case AtomicExpr::AO__hip_atomic_load:
4905 case AtomicExpr::AO__atomic_load_n:
4906 case AtomicExpr::AO__atomic_load:
4907 case AtomicExpr::AO__scoped_atomic_load_n:
4908 case AtomicExpr::AO__scoped_atomic_load:
4909 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4910 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4912 case AtomicExpr::AO__c11_atomic_store:
4913 case AtomicExpr::AO__opencl_atomic_store:
4914 case AtomicExpr::AO__hip_atomic_store:
4915 case AtomicExpr::AO__atomic_store:
4916 case AtomicExpr::AO__atomic_store_n:
4917 case AtomicExpr::AO__scoped_atomic_store:
4918 case AtomicExpr::AO__scoped_atomic_store_n:
4919 case AtomicExpr::AO__atomic_clear:
4920 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4921 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4922 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4952#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4953 case AtomicExpr::AO__hip_atomic_##hip: \
4954 OldName = "__hip_atomic_" #hip; \
4955 NewName = "__scoped_atomic_" #scoped; \
4968#undef HIP_ATOMIC_FIXABLE
4969 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4970 OldName =
"__hip_atomic_compare_exchange_weak";
4971 NewName =
"__scoped_atomic_compare_exchange";
4974 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4975 OldName =
"__hip_atomic_compare_exchange_strong";
4976 NewName =
"__scoped_atomic_compare_exchange";
4980 llvm_unreachable(
"unhandled HIP atomic op");
4983 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4984 << OldName << NewName;
4991 std::optional<llvm::APSInt> ScopeVal =
4996 StringRef ScopeName;
4997 switch (ScopeVal->getZExtValue()) {
4999 ScopeName =
"__MEMORY_SCOPE_SINGLE";
5002 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
5005 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
5008 ScopeName =
"__MEMORY_SCOPE_DEVICE";
5011 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
5014 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
5066 const unsigned NumForm = ClearByte + 1;
5067 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
5068 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
5076 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
5077 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
5078 "need to update code for modified forms");
5079 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
5080 AtomicExpr::AO__atomic_xor_fetch + 1 ==
5081 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
5082 "need to update code for modified C11 atomics");
5083 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
5084 Op <= AtomicExpr::AO__opencl_atomic_store;
5085 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
5086 Op <= AtomicExpr::AO__hip_atomic_store;
5087 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
5088 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
5089 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
5090 Op <= AtomicExpr::AO__c11_atomic_store) ||
5092 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
5093 Op == AtomicExpr::AO__atomic_store_n ||
5094 Op == AtomicExpr::AO__atomic_exchange_n ||
5095 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
5096 Op == AtomicExpr::AO__scoped_atomic_load_n ||
5097 Op == AtomicExpr::AO__scoped_atomic_store_n ||
5098 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
5099 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
5103 enum ArithOpExtraValueType {
5109 unsigned ArithAllows = AOEVT_None;
5112 case AtomicExpr::AO__c11_atomic_init:
5113 case AtomicExpr::AO__opencl_atomic_init:
5117 case AtomicExpr::AO__c11_atomic_load:
5118 case AtomicExpr::AO__opencl_atomic_load:
5119 case AtomicExpr::AO__hip_atomic_load:
5120 case AtomicExpr::AO__atomic_load_n:
5121 case AtomicExpr::AO__scoped_atomic_load_n:
5122 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5126 case AtomicExpr::AO__atomic_load:
5127 case AtomicExpr::AO__scoped_atomic_load:
5128 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5132 case AtomicExpr::AO__c11_atomic_store:
5133 case AtomicExpr::AO__opencl_atomic_store:
5134 case AtomicExpr::AO__hip_atomic_store:
5135 case AtomicExpr::AO__atomic_store:
5136 case AtomicExpr::AO__atomic_store_n:
5137 case AtomicExpr::AO__scoped_atomic_store:
5138 case AtomicExpr::AO__scoped_atomic_store_n:
5139 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5142 case AtomicExpr::AO__atomic_fetch_add:
5143 case AtomicExpr::AO__atomic_fetch_sub:
5144 case AtomicExpr::AO__atomic_add_fetch:
5145 case AtomicExpr::AO__atomic_sub_fetch:
5146 case AtomicExpr::AO__scoped_atomic_fetch_add:
5147 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5148 case AtomicExpr::AO__scoped_atomic_add_fetch:
5149 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5150 case AtomicExpr::AO__c11_atomic_fetch_add:
5151 case AtomicExpr::AO__c11_atomic_fetch_sub:
5152 case AtomicExpr::AO__opencl_atomic_fetch_add:
5153 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5154 case AtomicExpr::AO__hip_atomic_fetch_add:
5155 case AtomicExpr::AO__hip_atomic_fetch_sub:
5156 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5159 case AtomicExpr::AO__atomic_fetch_fminimum:
5160 case AtomicExpr::AO__atomic_fetch_fmaximum:
5161 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5162 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5163 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5164 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5165 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5166 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5167 ArithAllows = AOEVT_FP;
5170 case AtomicExpr::AO__atomic_fetch_max:
5171 case AtomicExpr::AO__atomic_fetch_min:
5172 case AtomicExpr::AO__atomic_max_fetch:
5173 case AtomicExpr::AO__atomic_min_fetch:
5174 case AtomicExpr::AO__scoped_atomic_fetch_max:
5175 case AtomicExpr::AO__scoped_atomic_fetch_min:
5176 case AtomicExpr::AO__scoped_atomic_max_fetch:
5177 case AtomicExpr::AO__scoped_atomic_min_fetch:
5178 case AtomicExpr::AO__c11_atomic_fetch_max:
5179 case AtomicExpr::AO__c11_atomic_fetch_min:
5180 case AtomicExpr::AO__opencl_atomic_fetch_max:
5181 case AtomicExpr::AO__opencl_atomic_fetch_min:
5182 case AtomicExpr::AO__hip_atomic_fetch_max:
5183 case AtomicExpr::AO__hip_atomic_fetch_min:
5184 ArithAllows = AOEVT_Int | AOEVT_FP;
5187 case AtomicExpr::AO__c11_atomic_fetch_and:
5188 case AtomicExpr::AO__c11_atomic_fetch_or:
5189 case AtomicExpr::AO__c11_atomic_fetch_xor:
5190 case AtomicExpr::AO__hip_atomic_fetch_and:
5191 case AtomicExpr::AO__hip_atomic_fetch_or:
5192 case AtomicExpr::AO__hip_atomic_fetch_xor:
5193 case AtomicExpr::AO__c11_atomic_fetch_nand:
5194 case AtomicExpr::AO__opencl_atomic_fetch_and:
5195 case AtomicExpr::AO__opencl_atomic_fetch_or:
5196 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5197 case AtomicExpr::AO__atomic_fetch_and:
5198 case AtomicExpr::AO__atomic_fetch_or:
5199 case AtomicExpr::AO__atomic_fetch_xor:
5200 case AtomicExpr::AO__atomic_fetch_nand:
5201 case AtomicExpr::AO__atomic_and_fetch:
5202 case AtomicExpr::AO__atomic_or_fetch:
5203 case AtomicExpr::AO__atomic_xor_fetch:
5204 case AtomicExpr::AO__atomic_nand_fetch:
5205 case AtomicExpr::AO__atomic_fetch_uinc:
5206 case AtomicExpr::AO__atomic_fetch_udec:
5207 case AtomicExpr::AO__scoped_atomic_fetch_and:
5208 case AtomicExpr::AO__scoped_atomic_fetch_or:
5209 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5210 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5211 case AtomicExpr::AO__scoped_atomic_and_fetch:
5212 case AtomicExpr::AO__scoped_atomic_or_fetch:
5213 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5214 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5215 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5216 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5220 case AtomicExpr::AO__c11_atomic_exchange:
5221 case AtomicExpr::AO__hip_atomic_exchange:
5222 case AtomicExpr::AO__opencl_atomic_exchange:
5223 case AtomicExpr::AO__atomic_exchange_n:
5224 case AtomicExpr::AO__scoped_atomic_exchange_n:
5225 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5229 case AtomicExpr::AO__atomic_exchange:
5230 case AtomicExpr::AO__scoped_atomic_exchange:
5231 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5235 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5236 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5237 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5238 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5239 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5240 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5244 case AtomicExpr::AO__atomic_compare_exchange:
5245 case AtomicExpr::AO__atomic_compare_exchange_n:
5246 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5247 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5248 ArithAllows = AOEVT_Pointer;
5252 case AtomicExpr::AO__atomic_test_and_set:
5253 Form = TestAndSetByte;
5256 case AtomicExpr::AO__atomic_clear:
5261 unsigned AdjustedNumArgs = NumArgs[Form];
5262 if ((IsOpenCL || IsHIP || IsScoped) &&
5263 Op != AtomicExpr::AO__opencl_atomic_init)
5266 if (Args.size() < AdjustedNumArgs) {
5267 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5268 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5271 }
else if (Args.size() > AdjustedNumArgs) {
5272 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5273 diag::err_typecheck_call_too_many_args)
5274 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5280 Expr *Ptr = Args[0];
5285 Ptr = ConvertedPtr.
get();
5288 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5289 << Ptr->getType() << 0 << Ptr->getSourceRange();
5298 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5299 << Ptr->getType() << Ptr->getSourceRange();
5304 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5306 << Ptr->getSourceRange();
5310 }
else if (Form != Load && Form != LoadCopy) {
5312 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5313 << Ptr->getType() << Ptr->getSourceRange();
5318 if (Form != TestAndSetByte && Form != ClearByte) {
5321 diag::err_incomplete_type))
5324 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5325 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5326 << Ptr->getType() << 1 << Ptr->getSourceRange();
5335 pointerType->getPointeeType().getCVRQualifiers());
5345 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5346 << 0 << Ptr->getType() << Ptr->getSourceRange();
5355 auto IsAllowedValueType = [&](
QualType ValType,
5356 unsigned AllowedType) ->
bool {
5357 bool IsX87LongDouble =
5359 &
Context.getTargetInfo().getLongDoubleFormat() ==
5360 &llvm::APFloat::x87DoubleExtended();
5364 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5366 return AllowedType & AOEVT_Pointer;
5370 if (IsX87LongDouble)
5374 if (!IsAllowedValueType(ValType, ArithAllows)) {
5376 ArithAllows == AOEVT_FP
5377 ? diag::err_atomic_op_needs_atomic_fp
5378 : (ArithAllows & AOEVT_FP
5379 ? (ArithAllows & AOEVT_Pointer
5380 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5381 : diag::err_atomic_op_needs_atomic_int_or_fp)
5382 : (ArithAllows & AOEVT_Pointer
5383 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5384 : diag::err_atomic_op_needs_atomic_int));
5386 << IsC11 << Ptr->getType() << Ptr->getSourceRange();
5391 diag::err_incomplete_type)) {
5402 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5403 << Ptr->getType() << Ptr->getSourceRange();
5418 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5419 << ValType << Ptr->getSourceRange();
5430 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5433 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5439 bool IsPassedByAddress =
false;
5440 if (!IsC11 && !IsHIP && !IsN) {
5441 ByValType = Ptr->getType();
5442 IsPassedByAddress =
true;
5447 APIOrderedArgs.push_back(Args[0]);
5451 APIOrderedArgs.push_back(Args[1]);
5457 APIOrderedArgs.push_back(Args[2]);
5458 APIOrderedArgs.push_back(Args[1]);
5461 APIOrderedArgs.push_back(Args[2]);
5462 APIOrderedArgs.push_back(Args[3]);
5463 APIOrderedArgs.push_back(Args[1]);
5466 APIOrderedArgs.push_back(Args[2]);
5467 APIOrderedArgs.push_back(Args[4]);
5468 APIOrderedArgs.push_back(Args[1]);
5469 APIOrderedArgs.push_back(Args[3]);
5472 APIOrderedArgs.push_back(Args[2]);
5473 APIOrderedArgs.push_back(Args[4]);
5474 APIOrderedArgs.push_back(Args[5]);
5475 APIOrderedArgs.push_back(Args[1]);
5476 APIOrderedArgs.push_back(Args[3]);
5478 case TestAndSetByte:
5480 APIOrderedArgs.push_back(Args[1]);
5484 APIOrderedArgs.append(Args.begin(), Args.end());
5491 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5493 if (i < NumVals[Form] + 1) {
5506 assert(Form != Load);
5508 Ty =
Context.getPointerDiffType();
5511 else if (Form ==
Copy || Form == Xchg) {
5512 if (IsPassedByAddress) {
5519 Expr *ValArg = APIOrderedArgs[i];
5526 AS = PtrTy->getPointeeType().getAddressSpace();
5535 if (IsPassedByAddress)
5555 APIOrderedArgs[i] = Arg.
get();
5560 SubExprs.push_back(Ptr);
5564 SubExprs.push_back(APIOrderedArgs[1]);
5567 case TestAndSetByte:
5569 SubExprs.push_back(APIOrderedArgs[1]);
5575 SubExprs.push_back(APIOrderedArgs[2]);
5576 SubExprs.push_back(APIOrderedArgs[1]);
5580 SubExprs.push_back(APIOrderedArgs[3]);
5581 SubExprs.push_back(APIOrderedArgs[1]);
5582 SubExprs.push_back(APIOrderedArgs[2]);
5585 SubExprs.push_back(APIOrderedArgs[3]);
5586 SubExprs.push_back(APIOrderedArgs[1]);
5587 SubExprs.push_back(APIOrderedArgs[4]);
5588 SubExprs.push_back(APIOrderedArgs[2]);
5591 SubExprs.push_back(APIOrderedArgs[4]);
5592 SubExprs.push_back(APIOrderedArgs[1]);
5593 SubExprs.push_back(APIOrderedArgs[5]);
5594 SubExprs.push_back(APIOrderedArgs[2]);
5595 SubExprs.push_back(APIOrderedArgs[3]);
5600 if (SubExprs.size() >= 2 && Form !=
Init) {
5601 std::optional<llvm::APSInt>
Success =
5602 SubExprs[1]->getIntegerConstantExpr(
Context);
5604 Diag(SubExprs[1]->getBeginLoc(),
5605 diag::warn_atomic_op_has_invalid_memory_order)
5606 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5607 << SubExprs[1]->getSourceRange();
5609 if (SubExprs.size() >= 5) {
5610 if (std::optional<llvm::APSInt>
Failure =
5611 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5612 if (!llvm::is_contained(
5613 {llvm::AtomicOrderingCABI::relaxed,
5614 llvm::AtomicOrderingCABI::consume,
5615 llvm::AtomicOrderingCABI::acquire,
5616 llvm::AtomicOrderingCABI::seq_cst},
5617 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5618 Diag(SubExprs[3]->getBeginLoc(),
5619 diag::warn_atomic_op_has_invalid_memory_order)
5620 << 2 << SubExprs[3]->getSourceRange();
5627 auto *
Scope = Args[Args.size() - 1];
5628 if (std::optional<llvm::APSInt>
Result =
5630 if (!ScopeModel->isValid(
Result->getZExtValue()))
5631 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5632 <<
Scope->getSourceRange();
5634 SubExprs.push_back(
Scope);
5643 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5644 Op == AtomicExpr::AO__c11_atomic_store ||
5645 Op == AtomicExpr::AO__opencl_atomic_load ||
5646 Op == AtomicExpr::AO__hip_atomic_load ||
5647 Op == AtomicExpr::AO__opencl_atomic_store ||
5648 Op == AtomicExpr::AO__hip_atomic_store) &&
5649 Context.AtomicUsesUnsupportedLibcall(AE))
5651 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5652 Op == AtomicExpr::AO__opencl_atomic_load ||
5653 Op == AtomicExpr::AO__hip_atomic_load)
5658 Diag(Ptr->getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5674 assert(Fn &&
"builtin call without direct callee!");
5690 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5697 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5699 <<
Callee->getSourceRange();
5708 Expr *FirstArg = TheCall->
getArg(0);
5712 FirstArg = FirstArgResult.
get();
5713 TheCall->
setArg(0, FirstArg);
5725 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5732 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5762 QualType ResultType = ValType;
5767#define BUILTIN_ROW(x) \
5768 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5769 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5771 static const unsigned BuiltinIndices[][5] = {
5796 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5797 case 1: SizeIndex = 0;
break;
5798 case 2: SizeIndex = 1;
break;
5799 case 4: SizeIndex = 2;
break;
5800 case 8: SizeIndex = 3;
break;
5801 case 16: SizeIndex = 4;
break;
5813 unsigned BuiltinIndex, NumFixed = 1;
5814 bool WarnAboutSemanticsChange =
false;
5815 switch (BuiltinID) {
5816 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5817 case Builtin::BI__sync_fetch_and_add:
5818 case Builtin::BI__sync_fetch_and_add_1:
5819 case Builtin::BI__sync_fetch_and_add_2:
5820 case Builtin::BI__sync_fetch_and_add_4:
5821 case Builtin::BI__sync_fetch_and_add_8:
5822 case Builtin::BI__sync_fetch_and_add_16:
5826 case Builtin::BI__sync_fetch_and_sub:
5827 case Builtin::BI__sync_fetch_and_sub_1:
5828 case Builtin::BI__sync_fetch_and_sub_2:
5829 case Builtin::BI__sync_fetch_and_sub_4:
5830 case Builtin::BI__sync_fetch_and_sub_8:
5831 case Builtin::BI__sync_fetch_and_sub_16:
5835 case Builtin::BI__sync_fetch_and_or:
5836 case Builtin::BI__sync_fetch_and_or_1:
5837 case Builtin::BI__sync_fetch_and_or_2:
5838 case Builtin::BI__sync_fetch_and_or_4:
5839 case Builtin::BI__sync_fetch_and_or_8:
5840 case Builtin::BI__sync_fetch_and_or_16:
5844 case Builtin::BI__sync_fetch_and_and:
5845 case Builtin::BI__sync_fetch_and_and_1:
5846 case Builtin::BI__sync_fetch_and_and_2:
5847 case Builtin::BI__sync_fetch_and_and_4:
5848 case Builtin::BI__sync_fetch_and_and_8:
5849 case Builtin::BI__sync_fetch_and_and_16:
5853 case Builtin::BI__sync_fetch_and_xor:
5854 case Builtin::BI__sync_fetch_and_xor_1:
5855 case Builtin::BI__sync_fetch_and_xor_2:
5856 case Builtin::BI__sync_fetch_and_xor_4:
5857 case Builtin::BI__sync_fetch_and_xor_8:
5858 case Builtin::BI__sync_fetch_and_xor_16:
5862 case Builtin::BI__sync_fetch_and_nand:
5863 case Builtin::BI__sync_fetch_and_nand_1:
5864 case Builtin::BI__sync_fetch_and_nand_2:
5865 case Builtin::BI__sync_fetch_and_nand_4:
5866 case Builtin::BI__sync_fetch_and_nand_8:
5867 case Builtin::BI__sync_fetch_and_nand_16:
5869 WarnAboutSemanticsChange =
true;
5872 case Builtin::BI__sync_add_and_fetch:
5873 case Builtin::BI__sync_add_and_fetch_1:
5874 case Builtin::BI__sync_add_and_fetch_2:
5875 case Builtin::BI__sync_add_and_fetch_4:
5876 case Builtin::BI__sync_add_and_fetch_8:
5877 case Builtin::BI__sync_add_and_fetch_16:
5881 case Builtin::BI__sync_sub_and_fetch:
5882 case Builtin::BI__sync_sub_and_fetch_1:
5883 case Builtin::BI__sync_sub_and_fetch_2:
5884 case Builtin::BI__sync_sub_and_fetch_4:
5885 case Builtin::BI__sync_sub_and_fetch_8:
5886 case Builtin::BI__sync_sub_and_fetch_16:
5890 case Builtin::BI__sync_and_and_fetch:
5891 case Builtin::BI__sync_and_and_fetch_1:
5892 case Builtin::BI__sync_and_and_fetch_2:
5893 case Builtin::BI__sync_and_and_fetch_4:
5894 case Builtin::BI__sync_and_and_fetch_8:
5895 case Builtin::BI__sync_and_and_fetch_16:
5899 case Builtin::BI__sync_or_and_fetch:
5900 case Builtin::BI__sync_or_and_fetch_1:
5901 case Builtin::BI__sync_or_and_fetch_2:
5902 case Builtin::BI__sync_or_and_fetch_4:
5903 case Builtin::BI__sync_or_and_fetch_8:
5904 case Builtin::BI__sync_or_and_fetch_16:
5908 case Builtin::BI__sync_xor_and_fetch:
5909 case Builtin::BI__sync_xor_and_fetch_1:
5910 case Builtin::BI__sync_xor_and_fetch_2:
5911 case Builtin::BI__sync_xor_and_fetch_4:
5912 case Builtin::BI__sync_xor_and_fetch_8:
5913 case Builtin::BI__sync_xor_and_fetch_16:
5917 case Builtin::BI__sync_nand_and_fetch:
5918 case Builtin::BI__sync_nand_and_fetch_1:
5919 case Builtin::BI__sync_nand_and_fetch_2:
5920 case Builtin::BI__sync_nand_and_fetch_4:
5921 case Builtin::BI__sync_nand_and_fetch_8:
5922 case Builtin::BI__sync_nand_and_fetch_16:
5924 WarnAboutSemanticsChange =
true;
5927 case Builtin::BI__sync_val_compare_and_swap:
5928 case Builtin::BI__sync_val_compare_and_swap_1:
5929 case Builtin::BI__sync_val_compare_and_swap_2:
5930 case Builtin::BI__sync_val_compare_and_swap_4:
5931 case Builtin::BI__sync_val_compare_and_swap_8:
5932 case Builtin::BI__sync_val_compare_and_swap_16:
5937 case Builtin::BI__sync_bool_compare_and_swap:
5938 case Builtin::BI__sync_bool_compare_and_swap_1:
5939 case Builtin::BI__sync_bool_compare_and_swap_2:
5940 case Builtin::BI__sync_bool_compare_and_swap_4:
5941 case Builtin::BI__sync_bool_compare_and_swap_8:
5942 case Builtin::BI__sync_bool_compare_and_swap_16:
5948 case Builtin::BI__sync_lock_test_and_set:
5949 case Builtin::BI__sync_lock_test_and_set_1:
5950 case Builtin::BI__sync_lock_test_and_set_2:
5951 case Builtin::BI__sync_lock_test_and_set_4:
5952 case Builtin::BI__sync_lock_test_and_set_8:
5953 case Builtin::BI__sync_lock_test_and_set_16:
5957 case Builtin::BI__sync_lock_release:
5958 case Builtin::BI__sync_lock_release_1:
5959 case Builtin::BI__sync_lock_release_2:
5960 case Builtin::BI__sync_lock_release_4:
5961 case Builtin::BI__sync_lock_release_8:
5962 case Builtin::BI__sync_lock_release_16:
5968 case Builtin::BI__sync_swap:
5969 case Builtin::BI__sync_swap_1:
5970 case Builtin::BI__sync_swap_2:
5971 case Builtin::BI__sync_swap_4:
5972 case Builtin::BI__sync_swap_8:
5973 case Builtin::BI__sync_swap_16:
5981 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5982 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5983 <<
Callee->getSourceRange();
5987 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5988 <<
Callee->getSourceRange();
5990 if (WarnAboutSemanticsChange) {
5991 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5992 <<
Callee->getSourceRange();
5997 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5998 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5999 FunctionDecl *NewBuiltinDecl;
6000 if (NewBuiltinID == BuiltinID)
6001 NewBuiltinDecl = FDecl;
6004 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
6007 assert(Res.getFoundDecl());
6008 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
6009 if (!NewBuiltinDecl)
6016 for (
unsigned i = 0; i != NumFixed; ++i) {
6045 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
6047 CK_BuiltinFnToFnPtr);
6058 const auto *BitIntValType = ValType->
getAs<BitIntType>();
6059 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
6060 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
6064 return TheCallResult;
6068 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
6073 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
6074 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
6075 "Unexpected nontemporal load/store builtin!");
6076 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
6077 unsigned numArgs = isStore ? 2 : 1;
6087 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
6093 PointerArg = PointerArgResult.
get();
6094 TheCall->
setArg(numArgs - 1, PointerArg);
6098 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
6111 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
6118 return TheCallResult;
6130 return TheCallResult;
6137 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6139 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6140 Literal = ObjcLiteral->getString();
6144 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6151 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6152 InitializedEntity Entity =
6162 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6163 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6164 TT.getArch() == llvm::Triple::aarch64_32);
6165 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6166 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6167 if (IsX64 || IsAArch64) {
6174 return S.
Diag(Fn->getBeginLoc(),
6175 diag::err_ms_va_start_used_in_sysv_function);
6182 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6183 return S.
Diag(Fn->getBeginLoc(),
6184 diag::err_va_start_used_in_wrong_abi_function)
6185 << !IsWindowsOrUEFI;
6191 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6199 bool IsVariadic =
false;
6203 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6204 IsVariadic =
Block->isVariadic();
6205 Params =
Block->parameters();
6206 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6209 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6210 IsVariadic = MD->isVariadic();
6212 Params = MD->parameters();
6215 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6219 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6224 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6229 *LastParam = Params.empty() ?
nullptr : Params.back();
6234bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6239 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6263 ParmVarDecl *LastParam;
6274 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6276 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6281 if (std::optional<llvm::APSInt> Val =
6283 Val &&
LangOpts.C23 && *Val == 0 &&
6284 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6285 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6292 SourceLocation ParamLoc;
6293 bool IsCRegister =
false;
6294 bool SecondArgIsLastNonVariadicArgument =
false;
6295 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6296 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6297 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6300 ParamLoc = PV->getLocation();
6306 if (!SecondArgIsLastNonVariadicArgument)
6308 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6309 else if (IsCRegister ||
Type->isReferenceType() ||
6310 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6313 if (!Context.isPromotableIntegerType(Type))
6315 const auto *ED = Type->getAsEnumDecl();
6318 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6320 unsigned Reason = 0;
6321 if (
Type->isReferenceType()) Reason = 1;
6322 else if (IsCRegister) Reason = 2;
6323 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6324 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6331 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6351 if (
Call->getNumArgs() < 3)
6353 diag::err_typecheck_call_too_few_args_at_least)
6354 << 0 << 3 <<
Call->getNumArgs()
6370 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6373 const QualType &ConstCharPtrTy =
6375 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6377 << Arg1->
getType() << ConstCharPtrTy << 1
6380 << 2 << Arg1->
getType() << ConstCharPtrTy;
6382 const QualType SizeTy =
Context.getSizeType();
6387 << Arg2->
getType() << SizeTy << 1
6390 << 3 << Arg2->
getType() << SizeTy;
6395bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6399 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6427 diag::err_typecheck_call_invalid_ordered_compare)
6435bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6436 unsigned BuiltinID) {
6441 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6442 BuiltinID == Builtin::BI__builtin_isinf ||
6443 BuiltinID == Builtin::BI__builtin_isinf_sign))
6447 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6448 BuiltinID == Builtin::BI__builtin_isunordered))
6452 bool IsFPClass = NumArgs == 2;
6455 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6459 for (
unsigned i = 0; i < FPArgNo; ++i) {
6460 Expr *Arg = TheCall->
getArg(i);
6473 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6482 OrigArg = Res.
get();
6484 TheCall->
setArg(FPArgNo, OrigArg);
6486 QualType VectorResultTy;
6487 QualType ElementTy = OrigArg->
getType();
6492 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6498 diag::err_typecheck_call_invalid_unary_fp)
6511 TheCall->
setArg(NumArgs - 1, MaskRes.
get());
6517 if (!VectorResultTy.
isNull())
6518 ResultTy = VectorResultTy;
6527bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6532 for (
unsigned I = 0; I != 2; ++I) {
6533 Expr *Arg = TheCall->
getArg(I);
6543 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6558 Expr *Real = TheCall->
getArg(0);
6559 Expr *Imag = TheCall->
getArg(1);
6562 diag::err_typecheck_call_different_arg_types)
6577 diag::err_typecheck_call_too_few_args_at_least)
6578 << 0 << 2 << NumArgs
6585 unsigned NumElements = 0;
6600 unsigned NumResElements = NumArgs - 2;
6607 if (RHSVecType->getElementType()->isBooleanType() ||
6608 !RHSVecType->getElementType()->isIntegerType()) {
6617 if (RHSVecType->getNumElements() != NumElements)
6619 diag::err_typecheck_vector_lengths_not_equal)
6620 << LHSType << RHSType <<
false
6623 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6625 diag::err_vec_builtin_incompatible_vector)
6630 }
else if (NumElements != NumResElements) {
6633 ?
Context.getExtVectorType(EltType, NumResElements)
6634 :
Context.getVectorType(EltType, NumResElements,
6639 for (
unsigned I = 2; I != NumArgs; ++I) {
6647 diag::err_shufflevector_nonconstant_argument)
6653 else if (
Result->getActiveBits() > 64 ||
6654 Result->getZExtValue() >= NumElements * 2)
6656 diag::err_shufflevector_argument_too_large)
6681 diag::err_convertvector_non_vector)
6684 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6686 <<
"__builtin_convertvector");
6691 if (SrcElts != DstElts)
6693 diag::err_convertvector_incompatible_vector)
6701bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6706 diag::err_typecheck_call_too_many_args_at_most)
6707 << 0 << 3 << NumArgs << 0
6712 for (
unsigned i = 1; i != NumArgs; ++i) {
6722bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6723 if (!
Context.getTargetInfo().checkArithmeticFenceSupported())
6724 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6728 Expr *Arg = TheCall->
getArg(0);
6732 QualType ArgTy = Arg->
getType();
6734 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6744bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6745 Expr *Arg = TheCall->
getArg(0);
6756bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6758 Expr *Arg = TheCall->
getArg(1);
6762 if (
const auto *UE =
6764 if (UE->getKind() == UETT_AlignOf ||
6765 UE->getKind() == UETT_PreferredAlignOf)
6771 if (!
Result.isPowerOf2())
6772 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6779 if (
Result > std::numeric_limits<int32_t>::max())
6787bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6792 Expr *FirstArg = TheCall->
getArg(0);
6798 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6802 TheCall->
setArg(0, FirstArgResult.
get());
6806 Expr *SecondArg = TheCall->
getArg(1);
6814 if (!
Result.isPowerOf2())
6815 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6827 Expr *ThirdArg = TheCall->
getArg(2);
6830 TheCall->
setArg(2, ThirdArg);
6836bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6837 unsigned BuiltinID =
6839 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6842 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6843 if (NumArgs < NumRequiredArgs) {
6844 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6845 << 0 << NumRequiredArgs << NumArgs
6848 if (NumArgs >= NumRequiredArgs + 0x100) {
6850 diag::err_typecheck_call_too_many_args_at_most)
6851 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6862 if (Arg.isInvalid())
6864 TheCall->
setArg(i, Arg.get());
6869 unsigned FormatIdx = i;
6879 unsigned FirstDataArg = i;
6880 while (i < NumArgs) {
6898 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6900 bool Success = CheckFormatArguments(
6903 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6927 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6936 int High,
bool RangeIsError) {
6950 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6958 PDiag(diag::warn_argument_invalid_range)
7001 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
7006 if (
Value.isNegative())
7017 if ((
Value & 0xFF) != 0)
7042 Result.setIsUnsigned(
true);
7047 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
7067 Result.setIsUnsigned(
true);
7075 diag::err_argument_not_shifted_byte_or_xxff)
7079bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
7080 if (!Context.getTargetInfo().hasSjLjLowering())
7081 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
7092 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
7098bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
7099 if (!Context.getTargetInfo().hasSjLjLowering())
7100 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
7105bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
7120 diag::err_builtin_counted_by_ref_invalid_arg)
7125 diag::err_builtin_counted_by_ref_has_side_effects)
7128 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
7130 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
7135 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
7142 QualType MemberTy = ME->getMemberDecl()->getType();
7145 diag::err_builtin_counted_by_ref_invalid_arg)
7149 diag::err_builtin_counted_by_ref_invalid_arg)
7159bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7161 const CallExpr *CE =
7170 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7175 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7180 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7184 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7188 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7198class UncoveredArgHandler {
7199 enum {
Unknown = -1, AllCovered = -2 };
7201 signed FirstUncoveredArg =
Unknown;
7202 SmallVector<const Expr *, 4> DiagnosticExprs;
7205 UncoveredArgHandler() =
default;
7207 bool hasUncoveredArg()
const {
7208 return (FirstUncoveredArg >= 0);
7211 unsigned getUncoveredArg()
const {
7212 assert(hasUncoveredArg() &&
"no uncovered argument");
7213 return FirstUncoveredArg;
7216 void setAllCovered() {
7219 DiagnosticExprs.clear();
7220 FirstUncoveredArg = AllCovered;
7223 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7224 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7227 if (FirstUncoveredArg == AllCovered)
7232 if (NewFirstUncoveredArg == FirstUncoveredArg)
7233 DiagnosticExprs.push_back(StrExpr);
7234 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7235 DiagnosticExprs.clear();
7236 DiagnosticExprs.push_back(StrExpr);
7237 FirstUncoveredArg = NewFirstUncoveredArg;
7241 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7244enum StringLiteralCheckType {
7246 SLCT_UncheckedLiteral,
7254 bool AddendIsRight) {
7255 unsigned BitWidth = Offset.getBitWidth();
7256 unsigned AddendBitWidth = Addend.getBitWidth();
7258 if (Addend.isUnsigned()) {
7259 Addend = Addend.zext(++AddendBitWidth);
7260 Addend.setIsSigned(
true);
7263 if (AddendBitWidth > BitWidth) {
7264 Offset = Offset.sext(AddendBitWidth);
7265 BitWidth = AddendBitWidth;
7266 }
else if (BitWidth > AddendBitWidth) {
7267 Addend = Addend.sext(BitWidth);
7271 llvm::APSInt ResOffset = Offset;
7272 if (BinOpKind == BO_Add)
7273 ResOffset = Offset.sadd_ov(Addend, Ov);
7275 assert(AddendIsRight && BinOpKind == BO_Sub &&
7276 "operator must be add or sub with addend on the right");
7277 ResOffset = Offset.ssub_ov(Addend, Ov);
7283 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7284 "index (intermediate) result too big");
7285 Offset = Offset.sext(2 * BitWidth);
7286 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7290 Offset = std::move(ResOffset);
7298class FormatStringLiteral {
7299 const StringLiteral *FExpr;
7303 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7304 : FExpr(fexpr), Offset(Offset) {}
7306 const StringLiteral *getFormatString()
const {
return FExpr; }
7308 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7310 unsigned getByteLength()
const {
7311 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7314 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7321 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7322 bool isWide()
const {
return FExpr->
isWide(); }
7323 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7324 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7325 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7326 bool isPascal()
const {
return FExpr->
isPascal(); }
7328 SourceLocation getLocationOfByte(
7329 unsigned ByteNo,
const SourceManager &SM,
const LangOptions &Features,
7330 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7331 unsigned *StartTokenByteOffset =
nullptr)
const {
7333 StartToken, StartTokenByteOffset);
7336 SourceLocation getBeginLoc() const LLVM_READONLY {
7340 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7346 Sema &S,
const FormatStringLiteral *FExpr,
7351 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7352 bool IgnoreStringsWithoutSpecifiers);
7361static StringLiteralCheckType
7367 llvm::SmallBitVector &CheckedVarArgs,
7368 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7369 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7370 bool IgnoreStringsWithoutSpecifiers =
false) {
7372 return SLCT_NotALiteral;
7374 assert(Offset.isSigned() &&
"invalid offset");
7377 return SLCT_NotALiteral;
7386 return SLCT_UncheckedLiteral;
7389 case Stmt::InitListExprClass:
7393 format_idx, firstDataArg,
Type, CallType,
7394 false, CheckedVarArgs,
7395 UncoveredArg, Offset, CallerFormatParamIdx,
7396 IgnoreStringsWithoutSpecifiers);
7398 return SLCT_NotALiteral;
7399 case Stmt::BinaryConditionalOperatorClass:
7400 case Stmt::ConditionalOperatorClass: {
7409 bool CheckLeft =
true, CheckRight =
true;
7412 if (
C->getCond()->EvaluateAsBooleanCondition(
7424 StringLiteralCheckType Left;
7426 Left = SLCT_UncheckedLiteral;
7429 Args, APK, format_idx, firstDataArg,
Type,
7430 CallType, InFunctionCall, CheckedVarArgs,
7431 UncoveredArg, Offset, CallerFormatParamIdx,
7432 IgnoreStringsWithoutSpecifiers);
7433 if (Left == SLCT_NotALiteral || !CheckRight) {
7439 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7440 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7441 UncoveredArg, Offset, CallerFormatParamIdx,
7442 IgnoreStringsWithoutSpecifiers);
7444 return (CheckLeft && Left < Right) ? Left : Right;
7447 case Stmt::ImplicitCastExprClass:
7451 case Stmt::OpaqueValueExprClass:
7456 return SLCT_NotALiteral;
7458 case Stmt::PredefinedExprClass:
7462 return SLCT_UncheckedLiteral;
7464 case Stmt::DeclRefExprClass: {
7470 bool isConstant =
false;
7474 isConstant = AT->getElementType().isConstant(S.
Context);
7476 isConstant =
T.isConstant(S.
Context) &&
7477 PT->getPointeeType().isConstant(S.
Context);
7478 }
else if (
T->isObjCObjectPointerType()) {
7481 isConstant =
T.isConstant(S.
Context);
7485 if (
const Expr *
Init = VD->getAnyInitializer()) {
7488 if (InitList->isStringLiteralInit())
7489 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7492 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7493 firstDataArg,
Type, CallType,
false,
7494 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7545 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7546 if (CallerFormatParamIdx)
7547 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7548 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7549 for (
const auto *PVFormatMatches :
7550 D->specific_attrs<FormatMatchesAttr>()) {
7555 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7559 S.
Diag(Args[format_idx]->getBeginLoc(),
7560 diag::warn_format_string_type_incompatible)
7561 << PVFormatMatches->getType()->getName()
7563 if (!InFunctionCall) {
7564 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7565 diag::note_format_string_defined);
7567 return SLCT_UncheckedLiteral;
7570 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7571 Args, APK, format_idx, firstDataArg,
Type, CallType,
7572 false, CheckedVarArgs, UncoveredArg,
7573 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7577 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7580 PVFormat->getFirstArg(), &CallerFSI))
7582 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7586 S.
Diag(Args[format_idx]->getBeginLoc(),
7587 diag::warn_format_string_type_incompatible)
7588 << PVFormat->getType()->getName()
7590 if (!InFunctionCall) {
7593 return SLCT_UncheckedLiteral;
7606 return SLCT_UncheckedLiteral;
7614 return SLCT_NotALiteral;
7617 case Stmt::CallExprClass:
7618 case Stmt::CXXMemberCallExprClass: {
7622 StringLiteralCheckType CommonResult;
7623 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7624 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7626 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7627 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7628 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7635 return CommonResult;
7637 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7639 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7640 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7643 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7644 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7645 UncoveredArg, Offset, CallerFormatParamIdx,
7646 IgnoreStringsWithoutSpecifiers);
7652 format_idx, firstDataArg,
Type, CallType,
7653 false, CheckedVarArgs,
7654 UncoveredArg, Offset, CallerFormatParamIdx,
7655 IgnoreStringsWithoutSpecifiers);
7656 return SLCT_NotALiteral;
7658 case Stmt::ObjCMessageExprClass: {
7660 if (
const auto *MD = ME->getMethodDecl()) {
7661 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7670 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7672 MD->getSelector().isKeywordSelector(
7673 {
"localizedStringForKey",
"value",
"table"})) {
7674 IgnoreStringsWithoutSpecifiers =
true;
7677 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7679 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7680 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7681 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7685 return SLCT_NotALiteral;
7687 case Stmt::ObjCStringLiteralClass:
7688 case Stmt::StringLiteralClass: {
7697 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7700 return SLCT_NotALiteral;
7702 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7704 format_idx, firstDataArg,
Type, InFunctionCall,
7705 CallType, CheckedVarArgs, UncoveredArg,
7706 IgnoreStringsWithoutSpecifiers);
7707 return SLCT_CheckedLiteral;
7710 return SLCT_NotALiteral;
7712 case Stmt::BinaryOperatorClass: {
7726 if (LIsInt != RIsInt) {
7730 if (BinOpKind == BO_Add) {
7743 return SLCT_NotALiteral;
7745 case Stmt::UnaryOperatorClass: {
7747 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7748 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7750 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7760 return SLCT_NotALiteral;
7764 return SLCT_NotALiteral;
7775 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7776 if (isa_and_nonnull<StringLiteral>(LVE))
7797 return "freebsd_kprintf";
7806 return llvm::StringSwitch<FormatStringType>(Flavor)
7808 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7813 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7829bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7833 llvm::SmallBitVector &CheckedVarArgs) {
7834 FormatStringInfo FSI;
7838 return CheckFormatArguments(
7839 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7844bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7848 llvm::SmallBitVector &CheckedVarArgs) {
7849 FormatStringInfo FSI;
7853 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7854 Format->getFormatString(), FSI.FormatIdx,
7856 CallType, Loc, Range, CheckedVarArgs);
7864 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7877 unsigned CallerArgumentIndexOffset =
7880 unsigned FirstArgumentIndex = -1;
7890 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7891 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7895 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7896 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7898 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7901 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7902 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7905 FirstArgumentIndex =
7906 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7912 ? (NumCallerParams + CallerArgumentIndexOffset)
7917 if (!ReferenceFormatString)
7923 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7925 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7927 std::string
Attr, Fixit;
7928 llvm::raw_string_ostream AttrOS(
Attr);
7930 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7931 << FirstArgumentIndex <<
")";
7933 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7935 AttrOS.write_escaped(ReferenceFormatString->
getString());
7939 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7950 llvm::raw_string_ostream IS(Fixit);
7958 if (LO.C23 || LO.CPlusPlus11)
7959 IS <<
"[[gnu::" <<
Attr <<
"]]";
7960 else if (LO.ObjC || LO.GNUMode)
7961 IS <<
"__attribute__((" <<
Attr <<
"))";
7975 Caller->
addAttr(FormatAttr::CreateImplicit(
7977 FormatStringIndex, FirstArgumentIndex));
7979 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7981 FormatStringIndex, ReferenceFormatString));
7985 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7997 unsigned format_idx,
unsigned firstDataArg,
8001 llvm::SmallBitVector &CheckedVarArgs) {
8003 if (format_idx >= Args.size()) {
8004 Diag(Loc, diag::warn_missing_format_string) <<
Range;
8008 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
8022 UncoveredArgHandler UncoveredArg;
8023 std::optional<unsigned> CallerParamIdx;
8025 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
8026 firstDataArg,
Type, CallType,
8027 true, CheckedVarArgs, UncoveredArg,
8028 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
8031 if (UncoveredArg.hasUncoveredArg()) {
8032 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
8033 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
8034 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
8037 if (CT != SLCT_NotALiteral)
8039 return CT == SLCT_CheckedLiteral;
8045 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
8051 this, Args, APK, ReferenceFormatString, format_idx,
8052 firstDataArg,
Type, *CallerParamIdx, Loc))
8062 if (Args.size() == firstDataArg) {
8063 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
8071 Diag(FormatLoc, diag::note_format_security_fixit)
8075 Diag(FormatLoc, diag::note_format_security_fixit)
8080 Diag(FormatLoc, diag::warn_format_nonliteral)
8091 const FormatStringLiteral *FExpr;
8092 const Expr *OrigFormatExpr;
8094 const unsigned FirstDataArg;
8095 const unsigned NumDataArgs;
8098 ArrayRef<const Expr *> Args;
8100 llvm::SmallBitVector CoveredArgs;
8101 bool usesPositionalArgs =
false;
8102 bool atFirstArg =
true;
8103 bool inFunctionCall;
8105 llvm::SmallBitVector &CheckedVarArgs;
8106 UncoveredArgHandler &UncoveredArg;
8109 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
8111 unsigned firstDataArg,
unsigned numDataArgs,
8113 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8115 llvm::SmallBitVector &CheckedVarArgs,
8116 UncoveredArgHandler &UncoveredArg)
8117 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
8118 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
8119 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
8120 inFunctionCall(inFunctionCall), CallType(callType),
8121 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
8122 CoveredArgs.resize(numDataArgs);
8123 CoveredArgs.reset();
8126 bool HasFormatArguments()
const {
8131 void DoneProcessing();
8133 void HandleIncompleteSpecifier(
const char *startSpecifier,
8134 unsigned specifierLen)
override;
8136 void HandleInvalidLengthModifier(
8137 const analyze_format_string::FormatSpecifier &FS,
8138 const analyze_format_string::ConversionSpecifier &CS,
8139 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
8141 void HandleNonStandardLengthModifier(
8142 const analyze_format_string::FormatSpecifier &FS,
8143 const char *startSpecifier,
unsigned specifierLen);
8145 void HandleNonStandardConversionSpecifier(
8146 const analyze_format_string::ConversionSpecifier &CS,
8147 const char *startSpecifier,
unsigned specifierLen);
8149 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
8151 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
8154 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
8156 void HandleNullChar(
const char *nullCharacter)
override;
8158 template <
typename Range>
8160 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8161 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8162 bool IsStringLocation, Range StringRange,
8163 ArrayRef<FixItHint> Fixit = {});
8166 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8167 const char *startSpec,
8168 unsigned specifierLen,
8169 const char *csStart,
unsigned csLen);
8171 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8172 const char *startSpec,
8173 unsigned specifierLen);
8175 SourceRange getFormatStringRange();
8176 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8177 unsigned specifierLen);
8178 SourceLocation getLocationOfByte(
const char *x);
8180 const Expr *getDataArg(
unsigned i)
const;
8182 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8183 const analyze_format_string::ConversionSpecifier &CS,
8184 const char *startSpecifier,
unsigned specifierLen,
8187 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8188 const Expr *E,
const char *startSpecifier,
8189 unsigned specifierLen);
8191 template <
typename Range>
8192 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8193 bool IsStringLocation, Range StringRange,
8194 ArrayRef<FixItHint> Fixit = {});
8199SourceRange CheckFormatHandler::getFormatStringRange() {
8204CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8205 unsigned specifierLen) {
8207 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8215SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8220void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8221 unsigned specifierLen) {
8222 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8223 getLocationOfByte(startSpecifier),
8225 getSpecifierRange(startSpecifier, specifierLen));
8228bool CheckFormatHandler::CheckUnsupportedType(
8230 const char *StartSpecifier,
unsigned SpecifierLen) {
8234 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8237 getSpecifierRange(StartSpecifier, SpecifierLen));
8241void CheckFormatHandler::HandleInvalidLengthModifier(
8244 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8256 getSpecifierRange(startSpecifier, specifierLen));
8258 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8259 << FixedLM->toString()
8264 if (DiagID == diag::warn_format_nonsensical_length)
8270 getSpecifierRange(startSpecifier, specifierLen), Hint);
8274void CheckFormatHandler::HandleNonStandardLengthModifier(
8276 const char *startSpecifier,
unsigned specifierLen) {
8285 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8289 getSpecifierRange(startSpecifier, specifierLen));
8291 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8292 << FixedLM->toString()
8296 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8300 getSpecifierRange(startSpecifier, specifierLen));
8304void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8306 const char *startSpecifier,
unsigned specifierLen) {
8312 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8316 getSpecifierRange(startSpecifier, specifierLen));
8319 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8320 << FixedCS->toString()
8323 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8327 getSpecifierRange(startSpecifier, specifierLen));
8331void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8333 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8334 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8335 getLocationOfByte(startPos),
8337 getSpecifierRange(startPos, posLen));
8340void CheckFormatHandler::HandleInvalidPosition(
8341 const char *startSpecifier,
unsigned specifierLen,
8344 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8345 EmitFormatDiagnostic(
8346 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8347 getLocationOfByte(startSpecifier),
true,
8348 getSpecifierRange(startSpecifier, specifierLen));
8351void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8355 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8356 getLocationOfByte(startPos),
8358 getSpecifierRange(startPos, posLen));
8361void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8364 EmitFormatDiagnostic(
8365 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8366 getLocationOfByte(nullCharacter),
true,
8367 getFormatStringRange());
8373const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8374 return Args[FirstDataArg + i];
8377void CheckFormatHandler::DoneProcessing() {
8380 if (HasFormatArguments()) {
8383 signed notCoveredArg = CoveredArgs.find_first();
8384 if (notCoveredArg >= 0) {
8385 assert((
unsigned)notCoveredArg < NumDataArgs);
8386 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8388 UncoveredArg.setAllCovered();
8393void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8394 const Expr *ArgExpr) {
8395 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8406 for (
auto E : DiagnosticExprs)
8409 CheckFormatHandler::EmitFormatDiagnostic(
8410 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8414bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8416 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8417 bool keepGoing =
true;
8418 if (argIndex < NumDataArgs) {
8421 CoveredArgs.set(argIndex);
8436 std::string CodePointStr;
8437 if (!llvm::sys::locale::isPrint(*csStart)) {
8438 llvm::UTF32 CodePoint;
8439 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8440 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8441 llvm::ConversionResult
Result =
8442 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8444 if (
Result != llvm::conversionOK) {
8445 unsigned char FirstChar = *csStart;
8446 CodePoint = (llvm::UTF32)FirstChar;
8449 llvm::raw_string_ostream
OS(CodePointStr);
8450 if (CodePoint < 256)
8451 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8452 else if (CodePoint <= 0xFFFF)
8453 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8455 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8459 EmitFormatDiagnostic(
8460 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8461 true, getSpecifierRange(startSpec, specifierLen));
8466void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8467 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8468 EmitFormatDiagnostic(
8469 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8470 true, getSpecifierRange(startSpec, specifierLen));
8473bool CheckFormatHandler::CheckNumArgs(
8476 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8478 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8481 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8482 << (argIndex + 1) << NumDataArgs)
8483 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8484 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8486 getSpecifierRange(startSpecifier, specifierLen));
8490 UncoveredArg.setAllCovered();
8496template <
typename Range>
8499 bool IsStringLocation,
8502 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8503 IsStringLocation, StringRange, FixIt);
8533template <
typename Range>
8534void CheckFormatHandler::EmitFormatDiagnostic(
8535 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8538 if (InFunctionCall) {
8543 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8547 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8548 diag::note_format_string_defined);
8550 Note << StringRange;
8559class CheckPrintfHandler :
public CheckFormatHandler {
8561 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8563 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8565 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8567 llvm::SmallBitVector &CheckedVarArgs,
8568 UncoveredArgHandler &UncoveredArg)
8569 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8570 numDataArgs, beg, APK, Args, formatIdx,
8571 inFunctionCall, CallType, CheckedVarArgs,
8574 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8577 bool allowsObjCArg()
const {
8578 return FSType == FormatStringType::NSString ||
8579 FSType == FormatStringType::OSLog ||
8580 FSType == FormatStringType::OSTrace;
8583 bool HandleInvalidPrintfConversionSpecifier(
8584 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8585 unsigned specifierLen)
override;
8587 void handleInvalidMaskType(StringRef MaskType)
override;
8589 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8590 const char *startSpecifier,
unsigned specifierLen,
8591 const TargetInfo &
Target)
override;
8592 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8593 const char *StartSpecifier,
unsigned SpecifierLen,
8596 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8597 unsigned k,
const char *startSpecifier,
8598 unsigned specifierLen);
8599 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8600 const analyze_printf::OptionalAmount &Amt,
8601 unsigned type,
const char *startSpecifier,
8602 unsigned specifierLen);
8603 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8604 const analyze_printf::OptionalFlag &flag,
8605 const char *startSpecifier,
unsigned specifierLen);
8606 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8607 const analyze_printf::OptionalFlag &ignoredFlag,
8608 const analyze_printf::OptionalFlag &flag,
8609 const char *startSpecifier,
unsigned specifierLen);
8610 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8612 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8613 unsigned flagLen)
override;
8615 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8616 unsigned flagLen)
override;
8619 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8620 const char *flagsEnd,
8621 const char *conversionPosition)
override;
8626class EquatableFormatArgument {
8628 enum SpecifierSensitivity :
unsigned {
8635 enum FormatArgumentRole :
unsigned {
8643 analyze_format_string::ArgType ArgType;
8644 analyze_format_string::LengthModifier LengthMod;
8645 StringRef SpecifierLetter;
8646 CharSourceRange
Range;
8647 SourceLocation ElementLoc;
8648 FormatArgumentRole
Role : 2;
8649 SpecifierSensitivity Sensitivity : 2;
8650 unsigned Position : 14;
8651 unsigned ModifierFor : 14;
8653 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8654 bool InFunctionCall)
const;
8657 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8658 analyze_format_string::LengthModifier LengthMod,
8659 StringRef SpecifierLetter,
8660 analyze_format_string::ArgType ArgType,
8661 FormatArgumentRole
Role,
8662 SpecifierSensitivity Sensitivity,
unsigned Position,
8663 unsigned ModifierFor)
8664 : ArgType(ArgType), LengthMod(LengthMod),
8665 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8666 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8667 ModifierFor(ModifierFor) {}
8669 unsigned getPosition()
const {
return Position; }
8670 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8672 analyze_format_string::LengthModifier getLengthModifier()
const {
8675 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8677 std::string buildFormatSpecifier()
const {
8679 llvm::raw_string_ostream(result)
8680 << getLengthModifier().
toString() << SpecifierLetter;
8684 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8685 const Expr *FmtExpr,
bool InFunctionCall)
const;
8689class DecomposePrintfHandler :
public CheckPrintfHandler {
8690 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8693 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8694 const Expr *origFormatExpr,
8696 unsigned numDataArgs,
bool isObjC,
const char *beg,
8698 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8700 llvm::SmallBitVector &CheckedVarArgs,
8701 UncoveredArgHandler &UncoveredArg,
8702 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8703 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8704 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8705 inFunctionCall, CallType, CheckedVarArgs,
8707 Specs(Specs), HadError(
false) {}
8711 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8713 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8715 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8716 const char *startSpecifier,
8717 unsigned specifierLen,
8718 const TargetInfo &
Target)
override;
8723bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8725 unsigned specifierLen) {
8729 return HandleInvalidConversionSpecifier(
8734void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8735 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8743 return T->isRecordType() ||
T->isComplexType();
8746bool CheckPrintfHandler::HandleAmount(
8748 const char *startSpecifier,
unsigned specifierLen) {
8750 if (HasFormatArguments()) {
8752 if (argIndex >= NumDataArgs) {
8753 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8757 getSpecifierRange(startSpecifier, specifierLen));
8767 CoveredArgs.set(argIndex);
8768 const Expr *Arg = getDataArg(argIndex);
8779 ? diag::err_printf_asterisk_wrong_type
8780 : diag::warn_printf_asterisk_wrong_type;
8781 EmitFormatDiagnostic(S.
PDiag(DiagID)
8786 getSpecifierRange(startSpecifier, specifierLen));
8796void CheckPrintfHandler::HandleInvalidAmount(
8799 const char *startSpecifier,
unsigned specifierLen) {
8809 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8813 getSpecifierRange(startSpecifier, specifierLen), fixit);
8818 const char *startSpecifier,
8819 unsigned specifierLen) {
8823 EmitFormatDiagnostic(
8824 S.
PDiag(diag::warn_printf_nonsensical_flag)
8828 getSpecifierRange(startSpecifier, specifierLen),
8832void CheckPrintfHandler::HandleIgnoredFlag(
8836 unsigned specifierLen) {
8838 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8842 getSpecifierRange(startSpecifier, specifierLen),
8844 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8847void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8850 EmitFormatDiagnostic(
8851 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8852 true, getSpecifierRange(startFlag, flagLen));
8855void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8858 auto Range = getSpecifierRange(startFlag, flagLen);
8859 StringRef flag(startFlag, flagLen);
8860 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8861 getLocationOfByte(startFlag),
8866void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8867 const char *flagsStart,
const char *flagsEnd,
8868 const char *conversionPosition) {
8870 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8871 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8872 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8873 getLocationOfByte(conversionPosition),
8879 const Expr *FmtExpr,
8880 bool InFunctionCall)
const {
8881 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8882 ElementLoc,
true, Range);
8885bool EquatableFormatArgument::VerifyCompatible(
8886 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8887 bool InFunctionCall)
const {
8892 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8893 FmtExpr, InFunctionCall);
8894 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8898 if (
Role != FAR_Data) {
8899 if (ModifierFor !=
Other.ModifierFor) {
8902 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8903 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8904 FmtExpr, InFunctionCall);
8905 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8911 bool HadError =
false;
8912 if (Sensitivity !=
Other.Sensitivity) {
8915 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8916 << Sensitivity <<
Other.Sensitivity,
8917 FmtExpr, InFunctionCall);
8918 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8919 << 0 <<
Other.Range;
8922 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8926 case MK::MatchPromotion:
8930 case MK::NoMatchTypeConfusion:
8931 case MK::NoMatchPromotionTypeConfusion:
8933 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8934 << buildFormatSpecifier()
8935 <<
Other.buildFormatSpecifier(),
8936 FmtExpr, InFunctionCall);
8937 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8938 << 0 <<
Other.Range;
8941 case MK::NoMatchPedantic:
8943 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8944 << buildFormatSpecifier()
8945 <<
Other.buildFormatSpecifier(),
8946 FmtExpr, InFunctionCall);
8947 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8948 << 0 <<
Other.Range;
8951 case MK::NoMatchSignedness:
8953 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8954 << buildFormatSpecifier()
8955 <<
Other.buildFormatSpecifier(),
8956 FmtExpr, InFunctionCall);
8957 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8958 << 0 <<
Other.Range;
8964bool DecomposePrintfHandler::GetSpecifiers(
8965 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8968 StringRef
Data = FSL->getString();
8969 const char *Str =
Data.data();
8970 llvm::SmallBitVector BV;
8971 UncoveredArgHandler UA;
8972 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8973 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8985 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8986 const EquatableFormatArgument &B) {
8987 return A.getPosition() < B.getPosition();
8992bool DecomposePrintfHandler::HandlePrintfSpecifier(
8995 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
9010 const unsigned Unset = ~0;
9011 unsigned FieldWidthIndex = Unset;
9012 unsigned PrecisionIndex = Unset;
9016 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
9017 FieldWidthIndex = Specs.size();
9019 getSpecifierRange(startSpecifier, specifierLen),
9020 getLocationOfByte(FieldWidth.getStart()),
9022 FieldWidth.getArgType(S.
Context),
9023 EquatableFormatArgument::FAR_FieldWidth,
9024 EquatableFormatArgument::SS_None,
9025 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
9031 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
9032 PrecisionIndex = Specs.size();
9034 getSpecifierRange(startSpecifier, specifierLen),
9035 getLocationOfByte(Precision.getStart()),
9037 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
9038 EquatableFormatArgument::SS_None,
9039 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
9045 unsigned SpecIndex =
9047 if (FieldWidthIndex != Unset)
9048 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
9049 if (PrecisionIndex != Unset)
9050 Specs[PrecisionIndex].setModifierFor(SpecIndex);
9052 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
9054 Sensitivity = EquatableFormatArgument::SS_Private;
9056 Sensitivity = EquatableFormatArgument::SS_Public;
9058 Sensitivity = EquatableFormatArgument::SS_Sensitive;
9060 Sensitivity = EquatableFormatArgument::SS_None;
9063 getSpecifierRange(startSpecifier, specifierLen),
9066 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
9071 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
9076 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
9077 SpecIndex + 1, SpecIndex);
9085template<
typename MemberKind>
9096 R.suppressDiagnostics();
9103 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
9118 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9120 if ((*MI)->getMinRequiredArguments() == 0)
9128bool CheckPrintfHandler::checkForCStrMembers(
9135 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9138 if (
Method->getMinRequiredArguments() == 0 &&
9151bool CheckPrintfHandler::HandlePrintfSpecifier(
9164 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9165 startSpecifier, specifierLen);
9177 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9182 if (!CS.consumesDataArgument()) {
9190 if (argIndex < NumDataArgs) {
9194 CoveredArgs.set(argIndex);
9201 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9204 if (HasFormatArguments()) {
9206 CoveredArgs.set(argIndex + 1);
9209 const Expr *Ex = getDataArg(argIndex);
9213 : ArgType::CPointerTy;
9215 EmitFormatDiagnostic(
9216 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9220 getSpecifierRange(startSpecifier, specifierLen));
9223 Ex = getDataArg(argIndex + 1);
9226 EmitFormatDiagnostic(
9227 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9231 getSpecifierRange(startSpecifier, specifierLen));
9238 if (!allowsObjCArg() && CS.isObjCArg()) {
9239 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9246 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9253 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9254 getLocationOfByte(CS.getStart()),
9256 getSpecifierRange(startSpecifier, specifierLen));
9266 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9273 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9277 getSpecifierRange(startSpecifier, specifierLen));
9280 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9284 getSpecifierRange(startSpecifier, specifierLen));
9288 const llvm::Triple &Triple =
Target.getTriple();
9290 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9291 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9292 getLocationOfByte(CS.getStart()),
9294 getSpecifierRange(startSpecifier, specifierLen));
9300 startSpecifier, specifierLen);
9306 startSpecifier, specifierLen);
9312 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9313 getLocationOfByte(startSpecifier),
9315 getSpecifierRange(startSpecifier, specifierLen));
9324 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9326 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9335 startSpecifier, specifierLen);
9338 startSpecifier, specifierLen);
9343 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9344 diag::warn_format_nonsensical_length);
9346 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9348 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9349 diag::warn_format_non_standard_conversion_spec);
9352 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9355 if (!HasFormatArguments())
9358 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9361 const Expr *Arg = getDataArg(argIndex);
9365 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9377 case Stmt::ArraySubscriptExprClass:
9378 case Stmt::CallExprClass:
9379 case Stmt::CharacterLiteralClass:
9380 case Stmt::CXXBoolLiteralExprClass:
9381 case Stmt::DeclRefExprClass:
9382 case Stmt::FloatingLiteralClass:
9383 case Stmt::IntegerLiteralClass:
9384 case Stmt::MemberExprClass:
9385 case Stmt::ObjCArrayLiteralClass:
9386 case Stmt::ObjCBoolLiteralExprClass:
9387 case Stmt::ObjCBoxedExprClass:
9388 case Stmt::ObjCDictionaryLiteralClass:
9389 case Stmt::ObjCEncodeExprClass:
9390 case Stmt::ObjCIvarRefExprClass:
9391 case Stmt::ObjCMessageExprClass:
9392 case Stmt::ObjCPropertyRefExprClass:
9393 case Stmt::ObjCStringLiteralClass:
9394 case Stmt::ObjCSubscriptRefExprClass:
9395 case Stmt::ParenExprClass:
9396 case Stmt::StringLiteralClass:
9397 case Stmt::UnaryOperatorClass:
9404static std::pair<QualType, StringRef>
9410 StringRef Name = UserTy->getDecl()->getName();
9411 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9412 .Case(
"CFIndex", Context.getNSIntegerType())
9413 .Case(
"NSInteger", Context.getNSIntegerType())
9414 .Case(
"NSUInteger", Context.getNSUIntegerType())
9415 .Case(
"SInt32", Context.IntTy)
9416 .Case(
"UInt32", Context.UnsignedIntTy)
9420 return std::make_pair(CastTy, Name);
9422 TyTy = UserTy->desugar();
9426 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9436 StringRef TrueName, FalseName;
9439 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9441 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9443 if (TrueTy == FalseTy)
9444 return std::make_pair(TrueTy, TrueName);
9445 else if (TrueTy.
isNull())
9446 return std::make_pair(FalseTy, FalseName);
9447 else if (FalseTy.
isNull())
9448 return std::make_pair(TrueTy, TrueName);
9451 return std::make_pair(
QualType(), StringRef());
9470 From = VecTy->getElementType();
9472 To = VecTy->getElementType();
9483 diag::warn_format_conversion_argument_type_mismatch_signedness,
9487 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9494bool CheckPrintfHandler::checkFormatExpr(
9496 unsigned SpecifierLen,
const Expr *E) {
9507 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9508 ExprTy = TET->getUnderlyingExpr()->getType();
9511 if (
const OverflowBehaviorType *OBT =
9513 ExprTy = OBT->getUnderlyingType();
9527 getSpecifierRange(StartSpecifier, SpecifierLen);
9529 llvm::raw_svector_ostream os(FSString);
9531 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9542 getSpecifierRange(StartSpecifier, SpecifierLen);
9543 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9548 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9556 if (
Match == ArgType::Match)
9560 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9569 E = ICE->getSubExpr();
9579 if (OrigMatch == ArgType::NoMatchSignedness &&
9580 ImplicitMatch != ArgType::NoMatchSignedness)
9587 if (ImplicitMatch == ArgType::Match)
9605 if (
Match == ArgType::MatchPromotion)
9609 if (
Match == ArgType::MatchPromotion) {
9613 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9614 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9618 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9619 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9620 Match = ImplicitMatch;
9621 assert(
Match != ArgType::MatchPromotion);
9624 bool IsEnum =
false;
9625 bool IsScopedEnum =
false;
9628 IntendedTy = ED->getIntegerType();
9629 if (!ED->isScoped()) {
9630 ExprTy = IntendedTy;
9635 IsScopedEnum =
true;
9642 if (isObjCContext() &&
9653 const llvm::APInt &
V = IL->getValue();
9663 if (TD->getUnderlyingType() == IntendedTy)
9673 bool ShouldNotPrintDirectly =
false;
9674 StringRef CastTyName;
9677 std::tie(CastTy, CastTyName) =
9683 if (!IsScopedEnum &&
9684 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9688 IntendedTy = CastTy;
9689 ShouldNotPrintDirectly =
true;
9694 PrintfSpecifier fixedFS = FS;
9701 llvm::raw_svector_ostream os(buf);
9704 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9706 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9712 llvm_unreachable(
"expected non-matching");
9714 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9717 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9720 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9723 Diag = diag::warn_format_conversion_argument_type_mismatch;
9744 llvm::raw_svector_ostream CastFix(CastBuf);
9745 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9747 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9753 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9758 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9780 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9786 Name = TypedefTy->getDecl()->getName();
9790 ? diag::warn_format_argument_needs_cast_pedantic
9791 : diag::warn_format_argument_needs_cast;
9792 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9803 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9804 : diag::warn_format_conversion_argument_type_mismatch;
9806 EmitFormatDiagnostic(
9814 getSpecifierRange(StartSpecifier, SpecifierLen);
9818 bool EmitTypeMismatch =
false;
9822 bool EmitOSLogError =
false;
9831 llvm_unreachable(
"expected non-matching");
9833 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9836 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9839 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9843 Diag = diag::warn_format_conversion_argument_type_mismatch;
9847 if (!EmitOSLogError)
9848 EmitFormatDiagnostic(
9857 EmitTypeMismatch =
true;
9861 EmitOSLogError =
true;
9863 EmitFormatDiagnostic(
9864 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9865 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9869 checkForCStrMembers(AT, E);
9875 EmitTypeMismatch =
true;
9877 EmitFormatDiagnostic(
9878 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9879 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9893 EmitFormatDiagnostic(
9894 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
9899 if (EmitTypeMismatch) {
9905 EmitFormatDiagnostic(
9906 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9912 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9913 "format string specifier index out of range");
9914 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9924class CheckScanfHandler :
public CheckFormatHandler {
9926 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
9928 unsigned firstDataArg,
unsigned numDataArgs,
9930 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9932 llvm::SmallBitVector &CheckedVarArgs,
9933 UncoveredArgHandler &UncoveredArg)
9934 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
9935 numDataArgs, beg, APK, Args, formatIdx,
9936 inFunctionCall, CallType, CheckedVarArgs,
9939 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9940 const char *startSpecifier,
9941 unsigned specifierLen)
override;
9944 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9945 const char *startSpecifier,
9946 unsigned specifierLen)
override;
9948 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9953void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9955 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9956 getLocationOfByte(end),
true,
9957 getSpecifierRange(start, end - start));
9960bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9962 unsigned specifierLen) {
9966 return HandleInvalidConversionSpecifier(
9971bool CheckScanfHandler::HandleScanfSpecifier(
9973 unsigned specifierLen) {
9986 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9987 startSpecifier, specifierLen);
9998 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
10013 if (argIndex < NumDataArgs) {
10017 CoveredArgs.set(argIndex);
10023 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10024 diag::warn_format_nonsensical_length);
10026 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
10028 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10029 diag::warn_format_non_standard_conversion_spec);
10032 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
10035 if (!HasFormatArguments())
10038 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
10042 const Expr *Ex = getDataArg(argIndex);
10052 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
10063 ScanfSpecifier fixedFS = FS;
10068 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
10070 ? diag::warn_format_conversion_argument_type_mismatch_signedness
10071 : diag::warn_format_conversion_argument_type_mismatch;
10076 llvm::raw_svector_ostream os(buf);
10079 EmitFormatDiagnostic(
10084 getSpecifierRange(startSpecifier, specifierLen),
10086 getSpecifierRange(startSpecifier, specifierLen), os.str()));
10093 getSpecifierRange(startSpecifier, specifierLen));
10103 const Expr *FmtExpr,
bool InFunctionCall) {
10104 bool HadError =
false;
10105 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
10106 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
10107 while (FmtIter < FmtEnd && RefIter < RefEnd) {
10119 for (; FmtIter < FmtEnd; ++FmtIter) {
10123 if (FmtIter->getPosition() < RefIter->getPosition())
10127 if (FmtIter->getPosition() > RefIter->getPosition())
10131 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
10135 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
10136 return Arg.getPosition() != RefIter->getPosition();
10140 if (FmtIter < FmtEnd) {
10141 CheckFormatHandler::EmitFormatDiagnostic(
10142 S, InFunctionCall, FmtExpr,
10143 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
10144 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
10145 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
10146 }
else if (RefIter < RefEnd) {
10147 CheckFormatHandler::EmitFormatDiagnostic(
10148 S, InFunctionCall, FmtExpr,
10149 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
10152 << 1 << RefIter->getSourceRange();
10158 Sema &S,
const FormatStringLiteral *FExpr,
10163 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10164 bool IgnoreStringsWithoutSpecifiers) {
10166 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10167 CheckFormatHandler::EmitFormatDiagnostic(
10168 S, inFunctionCall, Args[format_idx],
10169 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10175 StringRef StrRef = FExpr->getString();
10176 const char *Str = StrRef.data();
10180 assert(
T &&
"String literal not of constant array type!");
10181 size_t TypeSize =
T->getZExtSize();
10182 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10183 const unsigned numDataArgs = Args.size() - firstDataArg;
10185 if (IgnoreStringsWithoutSpecifiers &&
10192 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10193 CheckFormatHandler::EmitFormatDiagnostic(
10194 S, inFunctionCall, Args[format_idx],
10195 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10196 FExpr->getBeginLoc(),
10202 if (StrLen == 0 && numDataArgs > 0) {
10203 CheckFormatHandler::EmitFormatDiagnostic(
10204 S, inFunctionCall, Args[format_idx],
10205 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10216 if (ReferenceFormatString ==
nullptr) {
10217 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10218 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10219 inFunctionCall, CallType, CheckedVarArgs,
10226 H.DoneProcessing();
10229 Type, ReferenceFormatString, FExpr->getFormatString(),
10230 inFunctionCall ?
nullptr : Args[format_idx]);
10233 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10234 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10235 CallType, CheckedVarArgs, UncoveredArg);
10239 H.DoneProcessing();
10255 FormatStringLiteral RefLit = AuthoritativeFormatString;
10256 FormatStringLiteral TestLit = TestedFormatString;
10258 bool DiagAtStringLiteral;
10259 if (FunctionCallArg) {
10260 Arg = FunctionCallArg;
10261 DiagAtStringLiteral =
false;
10263 Arg = TestedFormatString;
10264 DiagAtStringLiteral =
true;
10266 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10267 AuthoritativeFormatString,
Type,
10268 IsObjC,
true, RefArgs) &&
10269 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10270 DiagAtStringLiteral, FmtArgs)) {
10272 TestedFormatString, FmtArgs, Arg,
10273 DiagAtStringLiteral);
10286 FormatStringLiteral RefLit = Str;
10290 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10299 bool HadError =
false;
10300 auto Iter = Args.begin();
10301 auto End = Args.end();
10302 while (Iter != End) {
10303 const auto &FirstInGroup = *Iter;
10305 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10307 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10316 const char *Str = StrRef.data();
10319 assert(
T &&
"String literal not of constant array type!");
10320 size_t TypeSize =
T->getZExtSize();
10321 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10331 switch (AbsFunction) {
10335 case Builtin::BI__builtin_abs:
10336 return Builtin::BI__builtin_labs;
10337 case Builtin::BI__builtin_labs:
10338 return Builtin::BI__builtin_llabs;
10339 case Builtin::BI__builtin_llabs:
10342 case Builtin::BI__builtin_fabsf:
10343 return Builtin::BI__builtin_fabs;
10344 case Builtin::BI__builtin_fabs:
10345 return Builtin::BI__builtin_fabsl;
10346 case Builtin::BI__builtin_fabsl:
10349 case Builtin::BI__builtin_cabsf:
10350 return Builtin::BI__builtin_cabs;
10351 case Builtin::BI__builtin_cabs:
10352 return Builtin::BI__builtin_cabsl;
10353 case Builtin::BI__builtin_cabsl:
10356 case Builtin::BIabs:
10357 return Builtin::BIlabs;
10358 case Builtin::BIlabs:
10359 return Builtin::BIllabs;
10360 case Builtin::BIllabs:
10363 case Builtin::BIfabsf:
10364 return Builtin::BIfabs;
10365 case Builtin::BIfabs:
10366 return Builtin::BIfabsl;
10367 case Builtin::BIfabsl:
10370 case Builtin::BIcabsf:
10371 return Builtin::BIcabs;
10372 case Builtin::BIcabs:
10373 return Builtin::BIcabsl;
10374 case Builtin::BIcabsl:
10381 unsigned AbsType) {
10403 unsigned AbsFunctionKind) {
10404 unsigned BestKind = 0;
10405 uint64_t ArgSize = Context.getTypeSize(ArgType);
10406 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10409 if (Context.getTypeSize(ParamType) >= ArgSize) {
10412 else if (Context.hasSameType(ParamType, ArgType)) {
10428 if (
T->isIntegralOrEnumerationType())
10430 if (
T->isRealFloatingType())
10432 if (
T->isAnyComplexType())
10435 llvm_unreachable(
"Type not integer, floating, or complex");
10442 switch (ValueKind) {
10447 case Builtin::BI__builtin_fabsf:
10448 case Builtin::BI__builtin_fabs:
10449 case Builtin::BI__builtin_fabsl:
10450 case Builtin::BI__builtin_cabsf:
10451 case Builtin::BI__builtin_cabs:
10452 case Builtin::BI__builtin_cabsl:
10453 return Builtin::BI__builtin_abs;
10454 case Builtin::BIfabsf:
10455 case Builtin::BIfabs:
10456 case Builtin::BIfabsl:
10457 case Builtin::BIcabsf:
10458 case Builtin::BIcabs:
10459 case Builtin::BIcabsl:
10460 return Builtin::BIabs;
10466 case Builtin::BI__builtin_abs:
10467 case Builtin::BI__builtin_labs:
10468 case Builtin::BI__builtin_llabs:
10469 case Builtin::BI__builtin_cabsf:
10470 case Builtin::BI__builtin_cabs:
10471 case Builtin::BI__builtin_cabsl:
10472 return Builtin::BI__builtin_fabsf;
10473 case Builtin::BIabs:
10474 case Builtin::BIlabs:
10475 case Builtin::BIllabs:
10476 case Builtin::BIcabsf:
10477 case Builtin::BIcabs:
10478 case Builtin::BIcabsl:
10479 return Builtin::BIfabsf;
10485 case Builtin::BI__builtin_abs:
10486 case Builtin::BI__builtin_labs:
10487 case Builtin::BI__builtin_llabs:
10488 case Builtin::BI__builtin_fabsf:
10489 case Builtin::BI__builtin_fabs:
10490 case Builtin::BI__builtin_fabsl:
10491 return Builtin::BI__builtin_cabsf;
10492 case Builtin::BIabs:
10493 case Builtin::BIlabs:
10494 case Builtin::BIllabs:
10495 case Builtin::BIfabsf:
10496 case Builtin::BIfabs:
10497 case Builtin::BIfabsl:
10498 return Builtin::BIcabsf;
10501 llvm_unreachable(
"Unable to convert function");
10512 case Builtin::BI__builtin_abs:
10513 case Builtin::BI__builtin_fabs:
10514 case Builtin::BI__builtin_fabsf:
10515 case Builtin::BI__builtin_fabsl:
10516 case Builtin::BI__builtin_labs:
10517 case Builtin::BI__builtin_llabs:
10518 case Builtin::BI__builtin_cabs:
10519 case Builtin::BI__builtin_cabsf:
10520 case Builtin::BI__builtin_cabsl:
10521 case Builtin::BIabs:
10522 case Builtin::BIlabs:
10523 case Builtin::BIllabs:
10524 case Builtin::BIfabs:
10525 case Builtin::BIfabsf:
10526 case Builtin::BIfabsl:
10527 case Builtin::BIcabs:
10528 case Builtin::BIcabsf:
10529 case Builtin::BIcabsl:
10532 llvm_unreachable(
"Unknown Builtin type");
10538 unsigned AbsKind,
QualType ArgType) {
10539 bool EmitHeaderHint =
true;
10540 const char *HeaderName =
nullptr;
10541 std::string FunctionName;
10542 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10543 FunctionName =
"std::abs";
10544 if (ArgType->isIntegralOrEnumerationType()) {
10545 HeaderName =
"cstdlib";
10546 }
else if (ArgType->isRealFloatingType()) {
10547 HeaderName =
"cmath";
10549 llvm_unreachable(
"Invalid Type");
10555 R.suppressDiagnostics();
10558 for (
const auto *I : R) {
10561 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10563 FDecl = dyn_cast<FunctionDecl>(I);
10578 EmitHeaderHint =
false;
10590 R.suppressDiagnostics();
10593 if (R.isSingleResult()) {
10594 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10596 EmitHeaderHint =
false;
10600 }
else if (!R.empty()) {
10606 S.
Diag(Loc, diag::note_replace_abs_function)
10612 if (!EmitHeaderHint)
10615 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10619template <std::
size_t StrLen>
10621 const char (&Str)[StrLen]) {
10634 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10635 return llvm::is_contained(names, calleeName);
10640 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10641 "__builtin_nanf16",
"__builtin_nanf128"});
10643 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10644 "__builtin_inff16",
"__builtin_inff128"});
10646 llvm_unreachable(
"unknown MathCheck");
10650 if (FDecl->
getName() !=
"infinity")
10653 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10655 if (RDecl->
getName() !=
"numeric_limits")
10672 if (FPO.getNoHonorNaNs() &&
10675 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10676 << 1 << 0 <<
Call->getSourceRange();
10680 if (FPO.getNoHonorInfs() &&
10684 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10685 << 0 << 0 <<
Call->getSourceRange();
10689void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10691 if (
Call->getNumArgs() != 1)
10696 if (AbsKind == 0 && !IsStdAbs)
10699 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10700 QualType ParamType =
Call->getArg(0)->getType();
10705 std::string FunctionName =
10706 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10707 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10708 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10743 if (ArgValueKind == ParamValueKind) {
10744 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10748 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10749 << FDecl << ArgType << ParamType;
10751 if (NewAbsKind == 0)
10755 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10764 if (NewAbsKind == 0)
10767 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10768 << FDecl << ParamValueKind << ArgValueKind;
10771 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10777 if (!
Call || !FDecl)
return;
10781 if (
Call->getExprLoc().isMacroID())
return;
10784 if (
Call->getNumArgs() != 2)
return;
10787 if (!ArgList)
return;
10788 if (ArgList->size() != 1)
return;
10791 const auto& TA = ArgList->
get(0);
10793 QualType ArgType = TA.getAsType();
10797 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10798 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10799 if (!MTE)
return false;
10800 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10801 if (!
Num)
return false;
10802 if (
Num->getValue() != 0)
return false;
10806 const Expr *FirstArg =
Call->getArg(0);
10807 const Expr *SecondArg =
Call->getArg(1);
10808 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10809 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10812 if (IsFirstArgZero == IsSecondArgZero)
return;
10817 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10819 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10820 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10823 SourceRange RemovalRange;
10824 if (IsFirstArgZero) {
10825 RemovalRange = SourceRange(FirstRange.
getBegin(),
10832 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10847 const auto *Size = dyn_cast<BinaryOperator>(E);
10852 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10856 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10857 << SizeRange << FnName;
10858 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10863 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10874 bool &IsContained) {
10876 const Type *Ty =
T->getBaseElementTypeUnsafe();
10877 IsContained =
false;
10890 for (
auto *FD : RD->
fields()) {
10894 IsContained =
true;
10895 return ContainedRD;
10903 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10904 if (Unary->getKind() == UETT_SizeOf)
10913 if (!
SizeOf->isArgumentType())
10914 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10921 return SizeOf->getTypeOfArgument();
10927struct SearchNonTrivialToInitializeField
10930 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10932 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10935 SourceLocation SL) {
10936 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10937 asDerived().visitArray(PDIK, AT, SL);
10941 Super::visitWithKind(PDIK, FT, SL);
10944 void visitARCStrong(QualType FT, SourceLocation SL) {
10947 void visitARCWeak(QualType FT, SourceLocation SL) {
10950 void visitStruct(QualType FT, SourceLocation SL) {
10955 const ArrayType *AT, SourceLocation SL) {
10956 visit(getContext().getBaseElementType(AT), SL);
10958 void visitTrivial(QualType FT, SourceLocation SL) {}
10960 static void diag(QualType RT,
const Expr *E, Sema &S) {
10961 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10970struct SearchNonTrivialToCopyField
10972 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10974 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10977 SourceLocation SL) {
10978 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10979 asDerived().visitArray(PCK, AT, SL);
10983 Super::visitWithKind(PCK, FT, SL);
10986 void visitARCStrong(QualType FT, SourceLocation SL) {
10989 void visitARCWeak(QualType FT, SourceLocation SL) {
10992 void visitPtrAuth(QualType FT, SourceLocation SL) {
10995 void visitStruct(QualType FT, SourceLocation SL) {
11000 SourceLocation SL) {
11001 visit(getContext().getBaseElementType(AT), SL);
11004 SourceLocation SL) {}
11005 void visitTrivial(QualType FT, SourceLocation SL) {}
11006 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
11008 static void diag(QualType RT,
const Expr *E, Sema &S) {
11009 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
11024 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
11025 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
11058 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
11061 const Expr *SizeArg =
11062 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
11064 auto isLiteralZero = [](
const Expr *E) {
11074 if (isLiteralZero(SizeArg) &&
11081 if (BId == Builtin::BIbzero ||
11084 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
11085 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
11086 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
11087 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
11088 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
11096 if (BId == Builtin::BImemset &&
11100 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
11101 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
11106void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
11113 unsigned ExpectedNumArgs =
11114 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
11115 if (
Call->getNumArgs() < ExpectedNumArgs)
11118 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
11119 BId == Builtin::BIstrndup ? 1 : 2);
11121 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
11125 Call->getBeginLoc(),
Call->getRParenLoc()))
11137 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
11138 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
11141 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
11145 QualType DestTy = Dest->
getType();
11146 QualType PointeeTy;
11147 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11159 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11165 if (SizeOfArgTy != QualType()) {
11167 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11169 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11170 << FnName << SizeOfArgTy << ArgIdx
11177 PointeeTy = DestTy;
11180 if (PointeeTy == QualType())
11185 if (
const CXXRecordDecl *ContainedRD =
11188 unsigned OperationType = 0;
11189 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11192 if (ArgIdx != 0 || IsCmp) {
11193 if (BId == Builtin::BImemcpy)
11195 else if(BId == Builtin::BImemmove)
11202 PDiag(diag::warn_dyn_class_memaccess)
11203 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11204 << IsContained << ContainedRD << OperationType
11205 <<
Call->getCallee()->getSourceRange());
11207 BId != Builtin::BImemset)
11210 PDiag(diag::warn_arc_object_memaccess)
11211 << ArgIdx << FnName << PointeeTy
11212 <<
Call->getCallee()->getSourceRange());
11219 bool NonTriviallyCopyableCXXRecord =
11223 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11226 PDiag(diag::warn_cstruct_memaccess)
11227 << ArgIdx << FnName << PointeeTy << 0);
11228 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11229 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11230 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11234 PDiag(diag::warn_cxxstruct_memaccess)
11235 << FnName << PointeeTy);
11236 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11239 PDiag(diag::warn_cstruct_memaccess)
11240 << ArgIdx << FnName << PointeeTy << 1);
11241 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11242 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11243 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11247 PDiag(diag::warn_cxxstruct_memaccess)
11248 << FnName << PointeeTy);
11257 PDiag(diag::note_bad_memaccess_silence)
11263bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11265 llvm::FoldingSetNodeID SizeOfArgID;
11271 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11274 QualType DestTy = Dest->
getType();
11275 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11281 if (SizeOfArgID == llvm::FoldingSetNodeID())
11284 llvm::FoldingSetNodeID DestID;
11286 if (DestID == SizeOfArgID) {
11289 unsigned ActionIdx = 0;
11290 StringRef ReadableName = FnName->
getName();
11292 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11293 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11302 SourceLocation SL = SizeOfArg->
getExprLoc();
11317 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11318 << ReadableName << PointeeTy << DestTy << DSR
11321 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11322 << ActionIdx << SSR);
11358 if (CAT->getZExtSize() <= 1)
11366void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11370 unsigned NumArgs =
Call->getNumArgs();
11371 if ((NumArgs != 3) && (NumArgs != 4))
11376 const Expr *CompareWithSrc =
nullptr;
11379 Call->getBeginLoc(),
Call->getRParenLoc()))
11384 CompareWithSrc = Ex;
11387 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11388 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11389 SizeCall->getNumArgs() == 1)
11394 if (!CompareWithSrc)
11401 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11405 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11406 if (!CompareWithSrcDRE ||
11410 const Expr *OriginalSizeArg =
Call->getArg(2);
11411 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11418 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11422 SmallString<128> sizeString;
11423 llvm::raw_svector_ostream
OS(sizeString);
11428 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11435 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11436 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11437 return D1->getDecl() == D2->getDecl();
11442 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11451void Sema::CheckStrncatArguments(
const CallExpr *CE,
11466 unsigned PatternType = 0;
11474 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11475 if (BE->getOpcode() == BO_Sub) {
11476 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11477 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11488 if (PatternType == 0)
11504 QualType DstTy = DstArg->
getType();
11507 if (!isKnownSizeArray) {
11508 if (PatternType == 1)
11509 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11511 Diag(SL, diag::warn_strncat_src_size) << SR;
11515 if (PatternType == 1)
11516 Diag(SL, diag::warn_strncat_large_size) << SR;
11518 Diag(SL, diag::warn_strncat_src_size) << SR;
11520 SmallString<128> sizeString;
11521 llvm::raw_svector_ostream
OS(sizeString);
11529 Diag(SL, diag::note_strncat_wrong_size)
11534void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11543void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11545 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11546 const Decl *D = Lvalue->getDecl();
11547 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11548 if (!DD->getType()->isReferenceType())
11549 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11553 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11554 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11555 Lvalue->getMemberDecl());
11558void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11560 const auto *Lambda = dyn_cast<LambdaExpr>(
11565 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11566 << CalleeName << 2 ;
11569void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11571 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11572 if (Var ==
nullptr)
11576 << CalleeName << 0 << Var;
11579void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11582 llvm::raw_svector_ostream
OS(SizeString);
11585 if (Kind == clang::CK_BitCast &&
11586 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11588 if (Kind == clang::CK_IntegralToPointer &&
11590 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11593 switch (
Cast->getCastKind()) {
11594 case clang::CK_BitCast:
11595 case clang::CK_IntegralToPointer:
11596 case clang::CK_FunctionToPointerDecay:
11605 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11606 << CalleeName << 0 <<
OS.str();
11610void Sema::CheckFreeArguments(
const CallExpr *E) {
11611 const std::string CalleeName =
11616 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11618 case UnaryOperator::Opcode::UO_AddrOf:
11619 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11620 case UnaryOperator::Opcode::UO_Plus:
11621 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11626 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11628 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11630 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11631 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11632 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11638 << CalleeName << 1 ;
11643 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11644 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11648Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11657 Diag(ReturnLoc, diag::warn_null_ret)
11667 if (Op == OO_New || Op == OO_Array_New) {
11668 const FunctionProtoType *Proto
11672 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11678 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11683 if (
Context.getTargetInfo().getTriple().isPPC64())
11695 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11696 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11697 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11698 return FPLiteral && FPCast;
11701 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11707 llvm::APFloat TargetC = FPLiteral->
getValue();
11708 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11709 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11713 Diag(Loc, diag::warn_float_compare_literal)
11714 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11727 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11728 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11729 if (DRL->getDecl() == DRR->getDecl())
11737 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11738 if (FLL->isExact())
11740 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11741 if (FLR->isExact())
11745 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11746 CL &&
CL->getBuiltinCallee())
11749 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11750 CR && CR->getBuiltinCallee())
11754 Diag(Loc, diag::warn_floatingpoint_eq)
11775 IntRange(
unsigned Width,
bool NonNegative)
11776 : Width(Width), NonNegative(NonNegative) {}
11779 unsigned valueBits()
const {
11780 return NonNegative ? Width : Width - 1;
11784 static IntRange forBoolType() {
11785 return IntRange(1,
true);
11789 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11790 return forValueOfCanonicalType(
C,
11795 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11798 if (
const auto *VT = dyn_cast<VectorType>(
T))
11799 T = VT->getElementType().getTypePtr();
11800 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11801 T = MT->getElementType().getTypePtr();
11802 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11803 T = CT->getElementType().getTypePtr();
11804 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11805 T = AT->getValueType().getTypePtr();
11806 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11807 T = OBT->getUnderlyingType().getTypePtr();
11809 if (!
C.getLangOpts().CPlusPlus) {
11812 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11817 if (
Enum->isFixed()) {
11818 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11819 !
Enum->getIntegerType()->isSignedIntegerType());
11822 unsigned NumPositive =
Enum->getNumPositiveBits();
11823 unsigned NumNegative =
Enum->getNumNegativeBits();
11825 if (NumNegative == 0)
11826 return IntRange(NumPositive,
true);
11828 return IntRange(std::max(NumPositive + 1, NumNegative),
11832 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11833 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11846 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11849 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11850 T = VT->getElementType().getTypePtr();
11851 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11852 T = MT->getElementType().getTypePtr();
11853 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11854 T = CT->getElementType().getTypePtr();
11855 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11856 T = AT->getValueType().getTypePtr();
11858 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11859 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11860 T = OBT->getUnderlyingType().getTypePtr();
11862 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11863 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11872 static IntRange
join(IntRange L, IntRange R) {
11873 bool Unsigned = L.NonNegative &&
R.NonNegative;
11874 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11875 L.NonNegative &&
R.NonNegative);
11879 static IntRange bit_and(IntRange L, IntRange R) {
11880 unsigned Bits = std::max(L.Width,
R.Width);
11881 bool NonNegative =
false;
11882 if (L.NonNegative) {
11883 Bits = std::min(Bits, L.Width);
11884 NonNegative =
true;
11886 if (
R.NonNegative) {
11887 Bits = std::min(Bits,
R.Width);
11888 NonNegative =
true;
11890 return IntRange(Bits, NonNegative);
11894 static IntRange sum(IntRange L, IntRange R) {
11895 bool Unsigned = L.NonNegative &&
R.NonNegative;
11896 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11901 static IntRange difference(IntRange L, IntRange R) {
11905 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11906 bool Unsigned = L.NonNegative &&
R.Width == 0;
11907 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11913 static IntRange product(IntRange L, IntRange R) {
11917 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11918 bool Unsigned = L.NonNegative &&
R.NonNegative;
11919 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11924 static IntRange rem(IntRange L, IntRange R) {
11928 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11936 if (value.isSigned() && value.isNegative())
11937 return IntRange(value.getSignificantBits(),
false);
11939 if (value.getBitWidth() > MaxWidth)
11940 value = value.trunc(MaxWidth);
11944 return IntRange(value.getActiveBits(),
true);
11948 if (result.
isInt())
11955 R = IntRange::join(R, El);
11963 return IntRange::join(R, I);
11978 Ty = AtomicRHS->getValueType();
11997 bool InConstantContext,
11998 bool Approximate) {
12009 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
12010 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
12014 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
12016 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
12017 CE->getCastKind() == CK_BooleanToSignedIntegral;
12020 if (!isIntegerCast)
12021 return OutputTypeRange;
12024 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
12025 InConstantContext, Approximate);
12027 return std::nullopt;
12030 if (SubRange->Width >= OutputTypeRange.Width)
12031 return OutputTypeRange;
12035 return IntRange(SubRange->Width,
12036 SubRange->NonNegative || OutputTypeRange.NonNegative);
12039 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12042 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
12044 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
12045 InConstantContext, Approximate);
12050 Expr *TrueExpr = CO->getTrueExpr();
12052 return std::nullopt;
12054 std::optional<IntRange> L =
12057 return std::nullopt;
12059 Expr *FalseExpr = CO->getFalseExpr();
12061 return std::nullopt;
12063 std::optional<IntRange> R =
12066 return std::nullopt;
12068 return IntRange::join(*L, *R);
12071 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12072 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
12074 switch (BO->getOpcode()) {
12076 llvm_unreachable(
"builtin <=> should have class type");
12087 return IntRange::forBoolType();
12116 Combine = IntRange::bit_and;
12124 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
12125 if (I->getValue() == 1) {
12126 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
12127 return IntRange(R.Width,
true);
12137 case BO_ShrAssign: {
12139 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
12141 return std::nullopt;
12145 if (std::optional<llvm::APSInt> shift =
12146 BO->getRHS()->getIntegerConstantExpr(
C)) {
12147 if (shift->isNonNegative()) {
12148 if (shift->uge(L->Width))
12149 L->Width = (L->NonNegative ? 0 : 1);
12151 L->Width -= shift->getZExtValue();
12165 Combine = IntRange::sum;
12169 if (BO->getLHS()->getType()->isPointerType())
12172 Combine = IntRange::difference;
12177 Combine = IntRange::product;
12186 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12188 return std::nullopt;
12191 if (std::optional<llvm::APSInt> divisor =
12192 BO->getRHS()->getIntegerConstantExpr(
C)) {
12193 unsigned log2 = divisor->logBase2();
12194 if (
log2 >= L->Width)
12195 L->Width = (L->NonNegative ? 0 : 1);
12197 L->Width = std::min(L->Width -
log2, MaxWidth);
12205 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12207 return std::nullopt;
12209 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12213 Combine = IntRange::rem;
12225 unsigned opWidth =
C.getIntWidth(
T);
12227 InConstantContext, Approximate);
12229 return std::nullopt;
12232 InConstantContext, Approximate);
12234 return std::nullopt;
12236 IntRange
C = Combine(*L, *R);
12237 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
12238 C.Width = std::min(
C.Width, MaxWidth);
12242 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12243 switch (UO->getOpcode()) {
12246 return IntRange::forBoolType();
12254 if (
GetExprType(E)->hasUnsignedIntegerRepresentation()) {
12260 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12263 return std::nullopt;
12268 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12272 if (
GetExprType(E)->hasUnsignedIntegerRepresentation()) {
12278 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12281 return std::nullopt;
12286 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12296 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) {
12300 if (
const Expr *SourceExpr = OVE->getSourceExpr())
12306 return IntRange(BitField->getBitWidthValue(),
12307 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12310 return std::nullopt;
12316 bool InConstantContext,
12317 bool Approximate) {
12326 const llvm::fltSemantics &Src,
12327 const llvm::fltSemantics &Tgt) {
12328 llvm::APFloat truncated = value;
12331 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12332 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12334 return truncated.bitwiseIsEqual(value);
12343 const llvm::fltSemantics &Src,
12344 const llvm::fltSemantics &Tgt) {
12368 bool IsListInit =
false);
12383 return MacroName !=
"YES" && MacroName !=
"NO" &&
12384 MacroName !=
"true" && MacroName !=
"false";
12392 (!E->
getType()->isSignedIntegerType() ||
12407struct PromotedRange {
12409 llvm::APSInt PromotedMin;
12411 llvm::APSInt PromotedMax;
12413 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12415 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12416 else if (
R.Width >= BitWidth && !
Unsigned) {
12420 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12421 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12423 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12424 .extOrTrunc(BitWidth);
12425 PromotedMin.setIsUnsigned(
Unsigned);
12427 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12428 .extOrTrunc(BitWidth);
12429 PromotedMax.setIsUnsigned(
Unsigned);
12434 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12444 InRangeFlag = 0x40,
12447 Min =
LE | InRangeFlag,
12448 InRange = InRangeFlag,
12449 Max =
GE | InRangeFlag,
12452 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12457 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12458 Value.isUnsigned() == PromotedMin.isUnsigned());
12459 if (!isContiguous()) {
12460 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12461 if (
Value.isMinValue())
return Min;
12462 if (
Value.isMaxValue())
return Max;
12463 if (
Value >= PromotedMin)
return InRange;
12464 if (
Value <= PromotedMax)
return InRange;
12468 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12469 case -1:
return Less;
12470 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12472 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12473 case -1:
return InRange;
12474 case 0:
return Max;
12479 llvm_unreachable(
"impossible compare result");
12482 static std::optional<StringRef>
12484 if (Op == BO_Cmp) {
12486 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12488 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12489 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12490 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12491 return std::nullopt;
12498 }
else if (Op == BO_NE) {
12502 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12509 if (Op == BO_GE || Op == BO_LE)
12510 std::swap(TrueFlag, FalseFlag);
12513 return StringRef(
"true");
12515 return StringRef(
"false");
12516 return std::nullopt;
12523 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12524 if (ICE->getCastKind() != CK_IntegralCast &&
12525 ICE->getCastKind() != CK_NoOp)
12527 E = ICE->getSubExpr();
12536 enum ConstantValueKind {
12541 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12542 return BL->getValue() ? ConstantValueKind::LiteralTrue
12543 : ConstantValueKind::LiteralFalse;
12544 return ConstantValueKind::Miscellaneous;
12549 const llvm::APSInt &
Value,
12550 bool RhsConstant) {
12566 if (
Constant->getType()->isEnumeralType() &&
12572 if (!OtherValueRange)
12577 OtherT = AT->getValueType();
12578 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12582 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12588 bool OtherIsBooleanDespiteType =
12590 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12591 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12595 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12596 Value.isUnsigned());
12597 auto Cmp = OtherPromotedValueRange.compare(
Value);
12604 bool TautologicalTypeCompare =
false;
12606 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12607 Value.isUnsigned());
12608 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12611 TautologicalTypeCompare =
true;
12619 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12628 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12634 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12635 Other->getType()->isUnsignedIntegerOrEnumerationType())
12636 TautologicalTypeCompare =
true;
12641 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12642 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12646 llvm::raw_svector_ostream OS(PrettySourceValue);
12648 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12649 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12650 Constant->IgnoreParenImpCasts())) {
12651 OS << (BL->getValue() ?
"YES" :
"NO");
12656 if (!TautologicalTypeCompare) {
12658 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12664 if (IsObjCSignedCharBool) {
12666 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12667 << OS.str() << *
Result);
12674 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12678 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12679 : diag::warn_tautological_bool_compare)
12681 << OtherIsBooleanDespiteType << *
Result
12688 ? diag::warn_unsigned_enum_always_true_comparison
12689 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12690 : diag::warn_unsigned_always_true_comparison)
12691 : diag::warn_tautological_constant_compare;
12727 if (
T->isIntegralType(S.
Context)) {
12728 std::optional<llvm::APSInt> RHSValue =
12730 std::optional<llvm::APSInt> LHSValue =
12734 if (RHSValue && LHSValue)
12738 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12740 const bool RhsConstant = (
bool)RHSValue;
12741 Expr *Const = RhsConstant ? RHS : LHS;
12743 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12752 if (!
T->hasUnsignedIntegerRepresentation()) {
12766 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12768 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12774 Expr *signedOperand, *unsignedOperand;
12777 "unsigned comparison between two signed integer expressions?");
12778 signedOperand = LHS;
12779 unsignedOperand = RHS;
12781 signedOperand = RHS;
12782 unsignedOperand = LHS;
12788 std::optional<IntRange> signedRange =
12800 if (signedRange->NonNegative)
12812 if (!unsignedRange)
12817 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12819 if (unsignedRange->Width < comparisonWidth)
12824 S.
PDiag(diag::warn_mixed_sign_comparison)
12843 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12848 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12849 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12850 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12851 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12852 << BitfieldEnumDecl;
12859 Init->isValueDependent() ||
12860 Init->isTypeDependent())
12863 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12873 const PreferredTypeAttr *PTAttr =
nullptr;
12875 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12877 ED = PTAttr->getType()->getAsEnumDecl();
12885 bool SignedEnum = ED->getNumNegativeBits() > 0;
12892 unsigned DiagID = 0;
12893 if (SignedEnum && !SignedBitfield) {
12896 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12898 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12899 }
else if (SignedBitfield && !SignedEnum &&
12900 ED->getNumPositiveBits() == FieldWidth) {
12903 ? diag::warn_signed_bitfield_enum_conversion
12904 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12907 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12912 << SignedEnum << TypeRange;
12914 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12921 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12922 ED->getNumNegativeBits())
12923 : ED->getNumPositiveBits();
12926 if (BitsNeeded > FieldWidth) {
12930 ? diag::warn_bitfield_too_small_for_enum
12931 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12932 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12936 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12946 unsigned OriginalWidth =
Value.getBitWidth();
12952 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12953 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12960 if (!
Value.isSigned() ||
Value.isNegative())
12961 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12962 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12963 OriginalWidth =
Value.getSignificantBits();
12965 if (OriginalWidth <= FieldWidth)
12969 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12973 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12974 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12978 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12980 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12981 ? diag::warn_impcast_single_bit_bitield_precision_constant
12982 : diag::warn_impcast_bitfield_precision_constant)
12983 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12984 <<
Init->getSourceRange();
13021 bool PruneControlFlow =
false) {
13028 if (
T.hasAddressSpace())
13030 if (PruneControlFlow) {
13044 bool PruneControlFlow =
false) {
13051 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
13056 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
13057 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
13062 llvm::APFloat
Value(0.0);
13068 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
13073 diag::warn_impcast_float_integer, PruneWarnings);
13076 bool isExact =
false;
13079 T->hasUnsignedIntegerRepresentation());
13080 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
13081 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
13089 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
13090 precision = (precision * 59 + 195) / 196;
13091 Value.toString(PrettySourceValue, precision);
13095 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
13096 << PrettySourceValue);
13099 if (
Result == llvm::APFloat::opOK && isExact) {
13100 if (IsLiteral)
return;
13101 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
13107 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
13110 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
13111 : diag::warn_impcast_float_to_integer_out_of_range,
13114 unsigned DiagID = 0;
13117 DiagID = diag::warn_impcast_literal_float_to_integer;
13118 }
else if (IntegerValue == 0) {
13119 if (
Value.isZero()) {
13121 diag::warn_impcast_float_integer, PruneWarnings);
13124 DiagID = diag::warn_impcast_float_to_integer_zero;
13126 if (IntegerValue.isUnsigned()) {
13127 if (!IntegerValue.isMaxValue()) {
13129 diag::warn_impcast_float_integer, PruneWarnings);
13132 if (!IntegerValue.isMaxSignedValue() &&
13133 !IntegerValue.isMinSignedValue()) {
13135 diag::warn_impcast_float_integer, PruneWarnings);
13139 DiagID = diag::warn_impcast_float_to_integer;
13144 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
13146 IntegerValue.toString(PrettyTargetValue);
13148 if (PruneWarnings) {
13151 << E->
getType() <<
T.getUnqualifiedType()
13152 << PrettySourceValue << PrettyTargetValue
13156 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
13165 "Must be compound assignment operation");
13176 ->getComputationResultType()
13183 if (ResultBT->isInteger())
13185 E->
getExprLoc(), diag::warn_impcast_float_integer);
13187 if (!ResultBT->isFloatingPoint())
13196 diag::warn_impcast_float_result_precision);
13201 if (!Range.Width)
return "0";
13203 llvm::APSInt ValueInRange =
Value;
13204 ValueInRange.setIsSigned(!Range.NonNegative);
13205 ValueInRange = ValueInRange.trunc(Range.Width);
13206 return toString(ValueInRange, 10);
13216 const Type *Source =
13218 if (
Target->isDependentType())
13221 const auto *FloatCandidateBT =
13222 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13223 const Type *BoolCandidateType = ToBool ?
Target : Source;
13226 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13231 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13237 S, TheCall->
getArg(I - 1),
false));
13239 S, TheCall->
getArg(I + 1),
false));
13244 diag::warn_impcast_floating_point_to_bool);
13259 if (!IsGNUNullExpr && !HasNullPtrType)
13263 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
13264 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
13267 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13280 if (IsGNUNullExpr && Loc.
isMacroID()) {
13283 if (MacroName ==
"NULL")
13291 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13306 const char FirstLiteralCharacter =
13308 if (FirstLiteralCharacter ==
'0')
13314 if (
T->isCharType() && !
T->isSignedIntegerType() && CC.
isValid()) {
13315 const char FirstContextCharacter =
13317 if (FirstContextCharacter ==
'{')
13325 const auto *IL = dyn_cast<IntegerLiteral>(E);
13327 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13328 if (UO->getOpcode() == UO_Minus)
13329 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13340 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13344 if (Opc == BO_Shl) {
13347 if (LHS && LHS->getValue() == 0)
13348 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13350 RHS->getValue().isNonNegative() &&
13352 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13353 << (
Result.Val.getInt() != 0);
13355 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13362 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13367 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13368 (RHS->getValue() == 0 || RHS->getValue() == 1))
13371 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13372 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13380 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13386 if (Source->isChar16Type() &&
Target->isChar32Type())
13392 llvm::APSInt
Value(32);
13394 bool IsASCII =
Value <= 0x7F;
13395 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13396 bool ConversionPreservesSemantics =
13397 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13399 if (!ConversionPreservesSemantics) {
13400 auto IsSingleCodeUnitCP = [](
const QualType &
T,
13401 const llvm::APSInt &
Value) {
13402 if (
T->isChar8Type())
13403 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13404 if (
T->isChar16Type())
13405 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13406 assert(
T->isChar32Type());
13407 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13410 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13419 LosesPrecision ? diag::warn_impcast_unicode_precision
13420 : diag::warn_impcast_unicode_char_type);
13425 From =
Context.getCanonicalType(From);
13426 To =
Context.getCanonicalType(To);
13429 From = MaybePointee;
13436 if (FromFn->getCFIUncheckedCalleeAttr() &&
13437 !ToFn->getCFIUncheckedCalleeAttr())
13445 bool *ICContext,
bool IsListInit) {
13450 if (Source ==
Target)
return;
13451 if (
Target->isDependentType())
return;
13461 if (Source->isAtomicType())
13465 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13471 diag::warn_impcast_string_literal_to_bool);
13477 diag::warn_impcast_objective_c_literal_to_bool);
13479 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13491 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
13494 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13496 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13505 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13507 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13518 diag::err_impcast_incompatible_type);
13523 ? diag::err_impcast_complex_scalar
13524 : diag::warn_impcast_complex_scalar);
13533 if (
Target->isSveVLSBuiltinType() &&
13540 if (
Target->isRVVVLSBuiltinType() &&
13550 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
13558 diag::warn_hlsl_impcast_vector_truncation);
13570 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13571 Target = VecTy->getElementType().getTypePtr();
13575 if (
Target->isScalarType())
13576 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
13584 diag::warn_hlsl_impcast_matrix_truncation);
13590 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13591 Target = MatTy->getElementType().getTypePtr();
13593 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13599 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
13602 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13604 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13651 else if (Order < 0) {
13661 if (TargetBT && TargetBT->
isInteger()) {
13688 diag::warn_impcast_floating_point_to_bool);
13696 if (Source->isFixedPointType()) {
13697 if (
Target->isUnsaturatedFixedPointType()) {
13701 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13702 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13703 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13706 PDiag(diag::warn_impcast_fixed_point_range)
13707 <<
Value.toString() <<
T
13713 }
else if (
Target->isIntegerType()) {
13717 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13720 llvm::APSInt IntResult = FXResult.convertToInt(
13721 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13726 PDiag(diag::warn_impcast_fixed_point_range)
13727 << FXResult.toString() <<
T
13734 }
else if (
Target->isUnsaturatedFixedPointType()) {
13735 if (Source->isIntegerType()) {
13742 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13747 PDiag(diag::warn_impcast_fixed_point_range)
13768 unsigned int SourcePrecision =
SourceRange->Width;
13772 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13775 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13776 SourcePrecision > TargetPrecision) {
13778 if (std::optional<llvm::APSInt> SourceInt =
13783 llvm::APFloat TargetFloatValue(
13785 llvm::APFloat::opStatus ConversionStatus =
13786 TargetFloatValue.convertFromAPInt(
13788 llvm::APFloat::rmNearestTiesToEven);
13790 if (ConversionStatus != llvm::APFloat::opOK) {
13792 SourceInt->toString(PrettySourceValue, 10);
13794 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13798 PDiag(diag::warn_impcast_integer_float_precision_constant)
13799 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13805 diag::warn_impcast_integer_float_precision);
13814 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13819 if (
Target->isBooleanType())
13823 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13827 if (!Source->isIntegerType() || !
Target->isIntegerType())
13832 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13835 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13838 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13843 if (!LikelySourceRange)
13846 IntRange SourceTypeRange =
13847 IntRange::forTargetOfCanonicalType(
Context, Source);
13848 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13850 if (LikelySourceRange->Width > TargetRange.Width) {
13854 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13855 if (TargetOBT->isWrapKind()) {
13862 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13863 if (SourceOBT->isWrapKind()) {
13873 llvm::APSInt
Value(32);
13883 PDiag(diag::warn_impcast_integer_precision_constant)
13884 << PrettySourceValue << PrettyTargetValue
13894 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13895 if (UO->getOpcode() == UO_Minus)
13897 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13900 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13904 diag::warn_impcast_integer_precision);
13907 if (TargetRange.Width > SourceTypeRange.Width) {
13908 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13909 if (UO->getOpcode() == UO_Minus)
13910 if (Source->isUnsignedIntegerType()) {
13911 if (
Target->isUnsignedIntegerType())
13913 diag::warn_impcast_high_order_zero_bits);
13914 if (
Target->isSignedIntegerType())
13916 diag::warn_impcast_nonnegative_result);
13920 if (TargetRange.Width == LikelySourceRange->Width &&
13921 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13922 Source->isSignedIntegerType()) {
13936 PDiag(diag::warn_impcast_integer_precision_constant)
13937 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13947 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13948 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13949 LikelySourceRange->Width == TargetRange.Width))) {
13953 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13955 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13959 unsigned DiagID = diag::warn_impcast_integer_sign;
13967 DiagID = diag::warn_impcast_integer_sign_conditional;
13984 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13986 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13987 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13988 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13989 TargetEnum->getDecl()->hasNameForLinkage() &&
13990 SourceEnum != TargetEnum) {
13995 diag::warn_impcast_different_enum_types);
14009 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
14022 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
14023 TrueExpr = BCO->getCommon();
14025 bool Suspicious =
false;
14029 if (
T->isBooleanType())
14034 if (!Suspicious)
return;
14037 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
14044 Suspicious =
false;
14049 E->
getType(), CC, &Suspicious);
14066struct AnalyzeImplicitConversionsWorkItem {
14075 bool ExtraCheckForImplicitConversion,
14078 WorkList.push_back({E, CC,
false});
14080 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
14087 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
14089 Expr *OrigE = Item.E;
14108 Expr *SourceExpr = E;
14113 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
14114 if (
auto *Src = OVE->getSourceExpr())
14117 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
14118 if (UO->getOpcode() == UO_Not &&
14119 UO->getSubExpr()->isKnownToHaveBooleanValue())
14120 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
14124 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
14125 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
14126 BO->getLHS()->isKnownToHaveBooleanValue() &&
14127 BO->getRHS()->isKnownToHaveBooleanValue() &&
14128 BO->getLHS()->HasSideEffects(S.
Context) &&
14129 BO->getRHS()->HasSideEffects(S.
Context)) {
14140 if (SR.str() ==
"&" || SR.str() ==
"|") {
14142 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
14143 << (BO->getOpcode() == BO_And ?
"&" :
"|")
14146 BO->getOperatorLoc(),
14147 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
14148 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
14150 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
14168 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14174 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14189 for (
auto *SE : POE->semantics())
14190 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14191 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14195 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14196 E = CE->getSubExpr();
14202 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14203 if (InitListE->getNumInits() == 1) {
14204 E = InitListE->getInit(0);
14211 WorkList.push_back({E, CC, IsListInit});
14215 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14216 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14220 if (OutArgE->isInOut())
14221 WorkList.push_back(
14222 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14223 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14229 if (BO->isComparisonOp())
14233 if (BO->getOpcode() == BO_Assign)
14236 if (BO->isAssignmentOp())
14252 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14254 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14258 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14259 if (ChildExpr == CSE->getOperand())
14265 if (IsLogicalAndOperator &&
14270 WorkList.push_back({ChildExpr, CC, IsListInit});
14284 if (
U->getOpcode() == UO_LNot) {
14286 }
else if (
U->getOpcode() != UO_AddrOf) {
14287 if (
U->getSubExpr()->getType()->isAtomicType())
14288 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14289 diag::warn_atomic_implicit_seq_cst);
14300 WorkList.push_back({OrigE, CC, IsListInit});
14301 while (!WorkList.empty())
14313 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14316 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14317 if (!M->getMemberDecl()->getType()->isReferenceType())
14319 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14320 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14322 FD =
Call->getDirectCallee();
14331 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14371 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14372 : diag::warn_this_bool_conversion;
14377 bool IsAddressOf =
false;
14379 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14380 if (UO->getOpcode() != UO_AddrOf)
14382 IsAddressOf =
true;
14383 E = UO->getSubExpr();
14387 unsigned DiagID = IsCompare
14388 ? diag::warn_address_of_reference_null_compare
14389 : diag::warn_address_of_reference_bool_conversion;
14397 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14400 llvm::raw_string_ostream S(Str);
14402 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14403 : diag::warn_cast_nonnull_to_bool;
14406 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14411 if (
auto *Callee =
Call->getDirectCallee()) {
14412 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14413 ComplainAboutNonnullParamOrCall(A);
14422 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14423 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14424 MRecordDecl && MRecordDecl->isLambda()) {
14427 << MRecordDecl->getSourceRange() << Range << IsEqual;
14437 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14438 D = M->getMemberDecl();
14446 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14449 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14450 ComplainAboutNonnullParamOrCall(A);
14454 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14458 auto ParamIter = llvm::find(FD->
parameters(), PV);
14460 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14464 ComplainAboutNonnullParamOrCall(
NonNull);
14469 if (ArgNo.getASTIndex() == ParamNo) {
14470 ComplainAboutNonnullParamOrCall(
NonNull);
14481 const bool IsFunctionReference =
14482 T->isReferenceType() &&
T->getPointeeType()->isFunctionType();
14483 if (IsFunctionReference)
14484 T =
T->getPointeeType();
14485 const bool IsArray =
T->isArrayType();
14486 const bool IsFunction =
T->isFunctionType();
14489 if (IsAddressOf && IsFunction) {
14494 if (!IsAddressOf && !IsFunction && !IsArray)
14499 llvm::raw_string_ostream S(Str);
14502 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14503 : diag::warn_impcast_pointer_to_bool;
14510 DiagType = AddressOf;
14511 else if (IsFunction)
14512 DiagType = FunctionPointer;
14514 DiagType = ArrayPointer;
14516 llvm_unreachable(
"Could not determine diagnostic.");
14518 << Range << IsEqual;
14521 if (!IsFunction || IsFunctionReference)
14532 if (ReturnType.
isNull())
14563 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14564 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14566 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14567 Target->isUnsignedIntegerType()) {
14571 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14572 : diag::warn_impcast_overflow_behavior_pedantic;
14576 ? diag::warn_impcast_overflow_behavior_assignment
14577 : diag::warn_impcast_overflow_behavior;
14583 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14584 if (TargetOBT->isWrapKind()) {
14604 CheckArrayAccess(E);
14614void Sema::CheckForIntOverflow (
const Expr *E) {
14616 SmallVector<const Expr *, 2> Exprs(1, E);
14619 const Expr *OriginalE = Exprs.pop_back_val();
14628 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14629 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14632 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14633 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14634 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14636 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14637 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14638 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14639 Exprs.push_back(Temporary->getSubExpr());
14640 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14641 Exprs.push_back(
Array->getIdx());
14642 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14643 Exprs.push_back(Compound->getInitializer());
14644 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14645 New &&
New->isArray()) {
14646 if (
auto ArraySize =
New->getArraySize())
14647 Exprs.push_back(*ArraySize);
14648 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14649 Exprs.push_back(MTE->getSubExpr());
14650 }
while (!Exprs.empty());
14658 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14665 class SequenceTree {
14667 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14668 unsigned Parent : 31;
14669 LLVM_PREFERRED_TYPE(
bool)
14670 unsigned Merged : 1;
14672 SmallVector<Value, 8> Values;
14678 friend class SequenceTree;
14682 explicit Seq(
unsigned N) : Index(N) {}
14685 Seq() : Index(0) {}
14688 SequenceTree() { Values.push_back(
Value(0)); }
14689 Seq root()
const {
return Seq(0); }
14694 Seq allocate(
Seq Parent) {
14695 Values.push_back(
Value(Parent.Index));
14696 return Seq(Values.size() - 1);
14701 Values[S.Index].Merged =
true;
14707 bool isUnsequenced(
Seq Cur,
Seq Old) {
14708 unsigned C = representative(Cur.Index);
14709 unsigned Target = representative(Old.Index);
14713 C = Values[
C].Parent;
14720 unsigned representative(
unsigned K) {
14721 if (Values[K].Merged)
14723 return Values[K].Parent = representative(Values[K].Parent);
14729 using Object =
const NamedDecl *;
14743 UK_ModAsSideEffect,
14745 UK_Count = UK_ModAsSideEffect + 1
14751 const Expr *UsageExpr =
nullptr;
14752 SequenceTree::Seq
Seq;
14758 Usage Uses[UK_Count];
14761 bool Diagnosed =
false;
14765 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14773 UsageInfoMap UsageMap;
14776 SequenceTree::Seq Region;
14780 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14784 SmallVectorImpl<const Expr *> &WorkList;
14791 struct SequencedSubexpression {
14792 SequencedSubexpression(SequenceChecker &
Self)
14793 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14794 Self.ModAsSideEffect = &ModAsSideEffect;
14797 ~SequencedSubexpression() {
14798 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14802 UsageInfo &UI =
Self.UsageMap[M.first];
14803 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14804 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14805 SideEffectUsage = M.second;
14807 Self.ModAsSideEffect = OldModAsSideEffect;
14810 SequenceChecker &
Self;
14811 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14812 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14819 class EvaluationTracker {
14821 EvaluationTracker(SequenceChecker &
Self)
14823 Self.EvalTracker =
this;
14826 ~EvaluationTracker() {
14827 Self.EvalTracker = Prev;
14829 Prev->EvalOK &= EvalOK;
14832 bool evaluate(
const Expr *E,
bool &
Result) {
14837 Self.SemaRef.isConstantEvaluatedContext());
14842 SequenceChecker &
Self;
14843 EvaluationTracker *Prev;
14844 bool EvalOK =
true;
14845 } *EvalTracker =
nullptr;
14849 Object getObject(
const Expr *E,
bool Mod)
const {
14851 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14852 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14853 return getObject(UO->getSubExpr(), Mod);
14854 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14855 if (BO->getOpcode() == BO_Comma)
14856 return getObject(BO->getRHS(), Mod);
14857 if (Mod && BO->isAssignmentOp())
14858 return getObject(BO->getLHS(), Mod);
14859 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14862 return ME->getMemberDecl();
14863 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14872 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14874 Usage &U = UI.Uses[UK];
14875 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14879 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14880 ModAsSideEffect->push_back(std::make_pair(O, U));
14882 U.UsageExpr = UsageExpr;
14892 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14893 UsageKind OtherKind,
bool IsModMod) {
14897 const Usage &U = UI.Uses[OtherKind];
14898 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14901 const Expr *Mod = U.UsageExpr;
14902 const Expr *ModOrUse = UsageExpr;
14903 if (OtherKind == UK_Use)
14904 std::swap(Mod, ModOrUse);
14908 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14909 : diag::warn_unsequenced_mod_use)
14910 << O << SourceRange(ModOrUse->
getExprLoc()));
14911 UI.Diagnosed =
true;
14940 void notePreUse(
Object O,
const Expr *UseExpr) {
14941 UsageInfo &UI = UsageMap[O];
14943 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14946 void notePostUse(
Object O,
const Expr *UseExpr) {
14947 UsageInfo &UI = UsageMap[O];
14948 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14950 addUsage(O, UI, UseExpr, UK_Use);
14953 void notePreMod(
Object O,
const Expr *ModExpr) {
14954 UsageInfo &UI = UsageMap[O];
14956 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14957 checkUsage(O, UI, ModExpr, UK_Use,
false);
14960 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14961 UsageInfo &UI = UsageMap[O];
14962 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14964 addUsage(O, UI, ModExpr, UK);
14968 SequenceChecker(Sema &S,
const Expr *E,
14969 SmallVectorImpl<const Expr *> &WorkList)
14970 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14974 (void)this->WorkList;
14977 void VisitStmt(
const Stmt *S) {
14981 void VisitExpr(
const Expr *E) {
14983 Base::VisitStmt(E);
14986 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14987 for (
auto *Sub : CSE->
children()) {
14988 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
15003 void VisitCastExpr(
const CastExpr *E) {
15015 void VisitSequencedExpressions(
const Expr *SequencedBefore,
15016 const Expr *SequencedAfter) {
15017 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
15018 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
15019 SequenceTree::Seq OldRegion = Region;
15022 SequencedSubexpression SeqBefore(*
this);
15023 Region = BeforeRegion;
15024 Visit(SequencedBefore);
15027 Region = AfterRegion;
15028 Visit(SequencedAfter);
15030 Region = OldRegion;
15032 Tree.merge(BeforeRegion);
15033 Tree.merge(AfterRegion);
15036 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
15041 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
15048 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15049 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15050 void VisitBinPtrMem(
const BinaryOperator *BO) {
15055 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15062 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15063 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15064 void VisitBinShlShr(
const BinaryOperator *BO) {
15068 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15075 void VisitBinComma(
const BinaryOperator *BO) {
15080 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15083 void VisitBinAssign(
const BinaryOperator *BO) {
15084 SequenceTree::Seq RHSRegion;
15085 SequenceTree::Seq LHSRegion;
15087 RHSRegion = Tree.allocate(Region);
15088 LHSRegion = Tree.allocate(Region);
15090 RHSRegion = Region;
15091 LHSRegion = Region;
15093 SequenceTree::Seq OldRegion = Region;
15109 SequencedSubexpression SeqBefore(*
this);
15110 Region = RHSRegion;
15114 Region = LHSRegion;
15118 notePostUse(O, BO);
15122 Region = LHSRegion;
15126 notePostUse(O, BO);
15128 Region = RHSRegion;
15136 Region = OldRegion;
15140 : UK_ModAsSideEffect);
15142 Tree.merge(RHSRegion);
15143 Tree.merge(LHSRegion);
15147 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
15148 VisitBinAssign(CAO);
15151 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15152 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15153 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
15156 return VisitExpr(UO);
15164 : UK_ModAsSideEffect);
15167 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15168 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15169 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15172 return VisitExpr(UO);
15176 notePostMod(O, UO, UK_ModAsSideEffect);
15179 void VisitBinLOr(
const BinaryOperator *BO) {
15185 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15186 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15187 SequenceTree::Seq OldRegion = Region;
15189 EvaluationTracker Eval(*
this);
15191 SequencedSubexpression Sequenced(*
this);
15192 Region = LHSRegion;
15199 bool EvalResult =
false;
15200 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15201 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15202 if (ShouldVisitRHS) {
15203 Region = RHSRegion;
15207 Region = OldRegion;
15208 Tree.merge(LHSRegion);
15209 Tree.merge(RHSRegion);
15212 void VisitBinLAnd(
const BinaryOperator *BO) {
15218 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15219 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15220 SequenceTree::Seq OldRegion = Region;
15222 EvaluationTracker Eval(*
this);
15224 SequencedSubexpression Sequenced(*
this);
15225 Region = LHSRegion;
15231 bool EvalResult =
false;
15232 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15233 bool ShouldVisitRHS = !EvalOK || EvalResult;
15234 if (ShouldVisitRHS) {
15235 Region = RHSRegion;
15239 Region = OldRegion;
15240 Tree.merge(LHSRegion);
15241 Tree.merge(RHSRegion);
15244 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15249 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15265 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15266 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15267 SequenceTree::Seq OldRegion = Region;
15269 EvaluationTracker Eval(*
this);
15271 SequencedSubexpression Sequenced(*
this);
15272 Region = ConditionRegion;
15282 bool EvalResult =
false;
15283 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15284 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15285 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15286 if (ShouldVisitTrueExpr) {
15287 Region = TrueRegion;
15290 if (ShouldVisitFalseExpr) {
15291 Region = FalseRegion;
15295 Region = OldRegion;
15296 Tree.merge(ConditionRegion);
15297 Tree.merge(TrueRegion);
15298 Tree.merge(FalseRegion);
15301 void VisitCallExpr(
const CallExpr *CE) {
15313 SequencedSubexpression Sequenced(*
this);
15318 SequenceTree::Seq CalleeRegion;
15319 SequenceTree::Seq OtherRegion;
15320 if (SemaRef.getLangOpts().CPlusPlus17) {
15321 CalleeRegion = Tree.allocate(Region);
15322 OtherRegion = Tree.allocate(Region);
15324 CalleeRegion = Region;
15325 OtherRegion = Region;
15327 SequenceTree::Seq OldRegion = Region;
15330 Region = CalleeRegion;
15332 SequencedSubexpression Sequenced(*this);
15333 Visit(CE->getCallee());
15335 Visit(CE->getCallee());
15339 Region = OtherRegion;
15343 Region = OldRegion;
15345 Tree.merge(CalleeRegion);
15346 Tree.merge(OtherRegion);
15364 return VisitCallExpr(CXXOCE);
15375 case OO_MinusEqual:
15377 case OO_SlashEqual:
15378 case OO_PercentEqual:
15379 case OO_CaretEqual:
15382 case OO_LessLessEqual:
15383 case OO_GreaterGreaterEqual:
15384 SequencingKind = RHSBeforeLHS;
15388 case OO_GreaterGreater:
15394 SequencingKind = LHSBeforeRHS;
15398 SequencingKind = LHSBeforeRest;
15402 SequencingKind = NoSequencing;
15406 if (SequencingKind == NoSequencing)
15407 return VisitCallExpr(CXXOCE);
15410 SequencedSubexpression Sequenced(*
this);
15413 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15414 "Should only get there with C++17 and above!");
15415 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15416 "Should only get there with an overloaded binary operator"
15417 " or an overloaded call operator!");
15419 if (SequencingKind == LHSBeforeRest) {
15420 assert(CXXOCE->getOperator() == OO_Call &&
15421 "We should only have an overloaded call operator here!");
15430 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15431 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15432 SequenceTree::Seq OldRegion = Region;
15434 assert(CXXOCE->getNumArgs() >= 1 &&
15435 "An overloaded call operator must have at least one argument"
15436 " for the postfix-expression!");
15437 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15438 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15439 CXXOCE->getNumArgs() - 1);
15443 Region = PostfixExprRegion;
15444 SequencedSubexpression Sequenced(*this);
15445 Visit(PostfixExpr);
15449 Region = ArgsRegion;
15450 for (const Expr *Arg : Args)
15453 Region = OldRegion;
15454 Tree.merge(PostfixExprRegion);
15455 Tree.merge(ArgsRegion);
15457 assert(CXXOCE->getNumArgs() == 2 &&
15458 "Should only have two arguments here!");
15459 assert((SequencingKind == LHSBeforeRHS ||
15460 SequencingKind == RHSBeforeLHS) &&
15461 "Unexpected sequencing kind!");
15465 const Expr *E1 = CXXOCE->getArg(0);
15466 const Expr *E2 = CXXOCE->getArg(1);
15467 if (SequencingKind == RHSBeforeLHS)
15470 return VisitSequencedExpressions(E1, E2);
15477 SequencedSubexpression Sequenced(*
this);
15480 return VisitExpr(CCE);
15483 SequenceExpressionsInOrder(
15489 return VisitExpr(ILE);
15492 SequenceExpressionsInOrder(ILE->
inits());
15504 SequenceTree::Seq Parent = Region;
15505 for (
const Expr *E : ExpressionList) {
15508 Region = Tree.allocate(Parent);
15509 Elts.push_back(Region);
15515 for (
unsigned I = 0; I < Elts.size(); ++I)
15516 Tree.merge(Elts[I]);
15520SequenceChecker::UsageInfo::UsageInfo() =
default;
15524void Sema::CheckUnsequencedOperations(
const Expr *E) {
15525 SmallVector<const Expr *, 8> WorkList;
15526 WorkList.push_back(E);
15527 while (!WorkList.empty()) {
15528 const Expr *Item = WorkList.pop_back_val();
15529 SequenceChecker(*
this, Item, WorkList);
15534 bool IsConstexpr) {
15537 CheckImplicitConversions(E, CheckLoc);
15539 CheckUnsequencedOperations(E);
15541 CheckForIntOverflow(E);
15554 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15558 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15562 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15576 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15580 bool CheckParameterNames) {
15581 bool HasInvalidParm =
false;
15583 assert(Param &&
"null in a parameter list");
15592 if (!Param->isInvalidDecl() &&
15594 diag::err_typecheck_decl_incomplete_type) ||
15596 diag::err_abstract_type_in_decl,
15598 Param->setInvalidDecl();
15599 HasInvalidParm =
true;
15604 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15608 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15616 QualType PType = Param->getOriginalType();
15624 if (!Param->isInvalidDecl()) {
15625 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15626 if (!ClassDecl->isInvalidDecl() &&
15627 !ClassDecl->hasIrrelevantDestructor() &&
15628 !ClassDecl->isDependentContext() &&
15629 ClassDecl->isParamDestroyedInCallee()) {
15641 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15642 if (!Param->getType().isConstQualified())
15643 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15647 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15652 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15653 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15658 if (!Param->isInvalidDecl() &&
15659 Param->getOriginalType()->isWebAssemblyTableType()) {
15660 Param->setInvalidDecl();
15661 HasInvalidParm =
true;
15662 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15666 return HasInvalidParm;
15669std::optional<std::pair<
15678static std::pair<CharUnits, CharUnits>
15686 if (
Base->isVirtual()) {
15693 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15700 DerivedType =
Base->getType();
15703 return std::make_pair(BaseAlignment, Offset);
15707static std::optional<std::pair<CharUnits, CharUnits>>
15713 return std::nullopt;
15718 return std::nullopt;
15722 CharUnits Offset = EltSize * IdxRes->getExtValue();
15725 return std::make_pair(P->first, P->second + Offset);
15731 return std::make_pair(
15732 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15738std::optional<std::pair<
15746 case Stmt::CStyleCastExprClass:
15747 case Stmt::CXXStaticCastExprClass:
15748 case Stmt::ImplicitCastExprClass: {
15750 const Expr *From = CE->getSubExpr();
15751 switch (CE->getCastKind()) {
15756 case CK_UncheckedDerivedToBase:
15757 case CK_DerivedToBase: {
15767 case Stmt::ArraySubscriptExprClass: {
15772 case Stmt::DeclRefExprClass: {
15776 if (!VD->getType()->isReferenceType()) {
15778 if (VD->hasDependentAlignment())
15787 case Stmt::MemberExprClass: {
15789 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15793 std::optional<std::pair<CharUnits, CharUnits>> P;
15802 return std::make_pair(P->first,
15805 case Stmt::UnaryOperatorClass: {
15815 case Stmt::BinaryOperatorClass: {
15827 return std::nullopt;
15832std::optional<std::pair<
15841 case Stmt::CStyleCastExprClass:
15842 case Stmt::CXXStaticCastExprClass:
15843 case Stmt::ImplicitCastExprClass: {
15845 const Expr *From = CE->getSubExpr();
15846 switch (CE->getCastKind()) {
15851 case CK_ArrayToPointerDecay:
15853 case CK_UncheckedDerivedToBase:
15854 case CK_DerivedToBase: {
15864 case Stmt::CXXThisExprClass: {
15869 case Stmt::UnaryOperatorClass: {
15875 case Stmt::BinaryOperatorClass: {
15884 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15885 std::swap(LHS, RHS);
15895 return std::nullopt;
15900 std::optional<std::pair<CharUnits, CharUnits>> P =
15904 return P->first.alignmentAtOffset(P->second);
15922 if (!DestPtr)
return;
15928 if (DestAlign.
isOne())
return;
15932 if (!SrcPtr)
return;
15943 if (SrcAlign >= DestAlign)
return;
15948 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15952void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15954 bool AllowOnePastEnd,
bool IndexNegated) {
15963 const Type *EffectiveType =
15967 Context.getAsConstantArrayType(BaseExpr->
getType());
15970 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15972 const Type *BaseType =
15974 bool IsUnboundedArray =
15976 Context, StrictFlexArraysLevel,
15979 (!IsUnboundedArray && BaseType->isDependentType()))
15987 if (IndexNegated) {
15988 index.setIsUnsigned(
false);
15992 if (IsUnboundedArray) {
15995 if (
index.isUnsigned() || !
index.isNegative()) {
15997 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15999 if (
index.getBitWidth() < AddrBits)
16001 std::optional<CharUnits> ElemCharUnits =
16002 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
16005 if (!ElemCharUnits || ElemCharUnits->isZero())
16007 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
16012 if (
index.getActiveBits() <= AddrBits) {
16014 llvm::APInt Product(
index);
16016 Product = Product.umul_ov(ElemBytes, Overflow);
16017 if (!Overflow && Product.getActiveBits() <= AddrBits)
16023 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
16024 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
16026 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
16027 MaxElems = MaxElems.udiv(ElemBytes);
16030 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
16031 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
16036 PDiag(DiagID) << index << AddrBits
16037 << (
unsigned)ASTC.toBits(*ElemCharUnits)
16038 << ElemBytes << MaxElems
16039 << MaxElems.getZExtValue()
16042 const NamedDecl *ND =
nullptr;
16044 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16046 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16048 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16049 ND = ME->getMemberDecl();
16053 PDiag(diag::note_array_declared_here) << ND);
16058 if (index.isUnsigned() || !index.isNegative()) {
16068 llvm::APInt size = ArrayTy->
getSize();
16070 if (BaseType != EffectiveType) {
16078 if (!ptrarith_typesize)
16079 ptrarith_typesize =
Context.getCharWidth();
16081 if (ptrarith_typesize != array_typesize) {
16083 uint64_t ratio = array_typesize / ptrarith_typesize;
16087 if (ptrarith_typesize * ratio == array_typesize)
16088 size *= llvm::APInt(size.getBitWidth(), ratio);
16092 if (size.getBitWidth() > index.getBitWidth())
16093 index = index.zext(size.getBitWidth());
16094 else if (size.getBitWidth() < index.getBitWidth())
16095 size = size.zext(index.getBitWidth());
16101 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
16108 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
16110 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
16111 SourceLocation IndexLoc =
16113 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
16118 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
16119 : diag::warn_ptr_arith_exceeds_bounds;
16120 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
16121 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
16125 << index << ArrayTy->
desugar() << CastMsg
16128 unsigned DiagID = diag::warn_array_index_precedes_bounds;
16130 DiagID = diag::warn_ptr_arith_precedes_bounds;
16131 if (index.isNegative()) index = -index;
16138 const NamedDecl *ND =
nullptr;
16140 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16142 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16144 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16145 ND = ME->getMemberDecl();
16149 PDiag(diag::note_array_declared_here) << ND);
16152void Sema::CheckArrayAccess(
const Expr *
expr) {
16153 int AllowOnePastEnd = 0;
16155 expr =
expr->IgnoreParenImpCasts();
16156 switch (
expr->getStmtClass()) {
16157 case Stmt::ArraySubscriptExprClass: {
16160 AllowOnePastEnd > 0);
16164 case Stmt::MemberExprClass: {
16168 case Stmt::CXXMemberCallExprClass: {
16172 case Stmt::ArraySectionExprClass: {
16178 nullptr, AllowOnePastEnd > 0);
16181 case Stmt::UnaryOperatorClass: {
16197 case Stmt::ConditionalOperatorClass: {
16199 if (
const Expr *lhs = cond->
getLHS())
16200 CheckArrayAccess(lhs);
16201 if (
const Expr *rhs = cond->
getRHS())
16202 CheckArrayAccess(rhs);
16205 case Stmt::CXXOperatorCallExprClass: {
16207 for (
const auto *Arg : OCE->arguments())
16208 CheckArrayAccess(Arg);
16218 Expr *RHS,
bool isProperty) {
16230 S.
Diag(Loc, diag::warn_arc_literal_assign)
16232 << (isProperty ? 0 : 1)
16240 Expr *RHS,
bool isProperty) {
16243 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16244 S.
Diag(Loc, diag::warn_arc_retained_assign)
16246 << (isProperty ? 0 : 1)
16250 RHS =
cast->getSubExpr();
16292 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16321 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16322 Diag(Loc, diag::warn_arc_retained_property_assign)
16326 RHS =
cast->getSubExpr();
16349 bool StmtLineInvalid;
16350 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16352 if (StmtLineInvalid)
16355 bool BodyLineInvalid;
16356 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16358 if (BodyLineInvalid)
16362 if (StmtLine != BodyLine)
16377 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16386 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16390 const Stmt *PossibleBody) {
16396 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16397 StmtLoc = FS->getRParenLoc();
16398 Body = FS->getBody();
16399 DiagID = diag::warn_empty_for_body;
16400 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16401 StmtLoc = WS->getRParenLoc();
16402 Body = WS->getBody();
16403 DiagID = diag::warn_empty_while_body;
16408 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16432 if (!ProbableTypo) {
16433 bool BodyColInvalid;
16434 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16436 if (BodyColInvalid)
16439 bool StmtColInvalid;
16442 if (StmtColInvalid)
16445 if (BodyCol > StmtCol)
16446 ProbableTypo =
true;
16449 if (ProbableTypo) {
16451 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16459 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16471 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16473 RHSExpr = CE->
getArg(0);
16474 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16475 CXXSCE && CXXSCE->isXValue())
16476 RHSExpr = CXXSCE->getSubExpr();
16480 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16481 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16484 if (LHSDeclRef && RHSDeclRef) {
16491 auto D =
Diag(OpLoc, diag::warn_self_move)
16507 const Expr *LHSBase = LHSExpr;
16508 const Expr *RHSBase = RHSExpr;
16509 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16510 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16511 if (!LHSME || !RHSME)
16514 while (LHSME && RHSME) {
16521 LHSME = dyn_cast<MemberExpr>(LHSBase);
16522 RHSME = dyn_cast<MemberExpr>(RHSBase);
16525 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16526 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16527 if (LHSDeclRef && RHSDeclRef) {
16534 Diag(OpLoc, diag::warn_self_move)
16541 Diag(OpLoc, diag::warn_self_move)
16565 bool AreUnionMembers =
false) {
16569 assert(((Field1Parent->isStructureOrClassType() &&
16570 Field2Parent->isStructureOrClassType()) ||
16571 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16572 "Can't evaluate layout compatibility between a struct field and a "
16574 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16575 (AreUnionMembers && Field1Parent->isUnionType())) &&
16576 "AreUnionMembers should be 'true' for union fields (only).");
16590 if (Bits1 != Bits2)
16594 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16595 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16598 if (!AreUnionMembers &&
16610 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16611 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16613 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16614 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16619 return isLayoutCompatible(C, F1, F2);
16630 for (
auto *Field1 : RD1->
fields()) {
16631 auto It = llvm::find_if(UnmatchedFields, [&](
const FieldDecl *Field2) {
16634 if (It == UnmatchedFields.end())
16636 [[maybe_unused]]
bool Result = UnmatchedFields.erase(*It);
16640 return UnmatchedFields.empty();
16666 if (
C.hasSameType(T1, T2))
16675 if (TC1 == Type::Enum)
16677 if (TC1 == Type::Record) {
16696 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16727 const ValueDecl **VD, uint64_t *MagicValue,
16728 bool isConstantEvaluated) {
16736 case Stmt::UnaryOperatorClass: {
16745 case Stmt::DeclRefExprClass: {
16751 case Stmt::IntegerLiteralClass: {
16753 llvm::APInt MagicValueAPInt = IL->
getValue();
16754 if (MagicValueAPInt.getActiveBits() <= 64) {
16755 *MagicValue = MagicValueAPInt.getZExtValue();
16761 case Stmt::BinaryConditionalOperatorClass:
16762 case Stmt::ConditionalOperatorClass: {
16767 isConstantEvaluated)) {
16777 case Stmt::BinaryOperatorClass: {
16780 TypeExpr = BO->
getRHS();
16810 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16813 bool isConstantEvaluated) {
16814 FoundWrongKind =
false;
16819 uint64_t MagicValue;
16821 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16825 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16826 if (I->getArgumentKind() != ArgumentKind) {
16827 FoundWrongKind =
true;
16830 TypeInfo.Type = I->getMatchingCType();
16831 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16832 TypeInfo.MustBeNull = I->getMustBeNull();
16843 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16844 if (I == MagicValues->end())
16853 bool LayoutCompatible,
16855 if (!TypeTagForDatatypeMagicValues)
16856 TypeTagForDatatypeMagicValues.reset(
16857 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16860 (*TypeTagForDatatypeMagicValues)[Magic] =
16876 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16877 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16878 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16879 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16882void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16885 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16886 bool IsPointerAttr = Attr->getIsPointer();
16889 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16890 if (TypeTagIdxAST >= ExprArgs.size()) {
16891 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16892 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16895 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16896 bool FoundWrongKind;
16899 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16901 if (FoundWrongKind)
16903 diag::warn_type_tag_for_datatype_wrong_kind)
16909 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16910 if (ArgumentIdxAST >= ExprArgs.size()) {
16911 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16912 << 1 << Attr->getArgumentIdx().getSourceIndex();
16915 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16916 if (IsPointerAttr) {
16918 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16919 if (ICE->getType()->isVoidPointerType() &&
16920 ICE->getCastKind() == CK_BitCast)
16921 ArgumentExpr = ICE->getSubExpr();
16923 QualType ArgumentType = ArgumentExpr->
getType();
16929 if (TypeInfo.MustBeNull) {
16934 diag::warn_type_safety_null_pointer_required)
16942 QualType RequiredType = TypeInfo.Type;
16944 RequiredType =
Context.getPointerType(RequiredType);
16946 bool mismatch =
false;
16947 if (!TypeInfo.LayoutCompatible) {
16948 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16969 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16970 << ArgumentType << ArgumentKind
16971 << TypeInfo.LayoutCompatible << RequiredType
16989 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16997 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
17003 auto &MisalignedMembersForExpr =
17005 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
17006 if (MA != MisalignedMembersForExpr.end() &&
17007 (
T->isDependentType() ||
T->isIntegerType() ||
17008 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
17010 T->getPointeeType()) <= MA->Alignment))))
17011 MisalignedMembersForExpr.erase(MA);
17020 const auto *ME = dyn_cast<MemberExpr>(E);
17032 bool AnyIsPacked =
false;
17034 QualType BaseType = ME->getBase()->getType();
17035 if (BaseType->isDependentType())
17039 auto *RD = BaseType->castAsRecordDecl();
17044 auto *FD = dyn_cast<FieldDecl>(MD);
17050 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
17051 ReverseMemberChain.push_back(FD);
17054 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
17056 assert(TopME &&
"We did not compute a topmost MemberExpr!");
17063 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
17074 if (ExpectedAlignment.
isOne())
17079 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
17080 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
17084 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
17088 if (DRE && !TopME->
isArrow()) {
17091 CompleteObjectAlignment =
17092 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
17096 if (!Offset.isMultipleOf(ExpectedAlignment) ||
17099 CompleteObjectAlignment < ExpectedAlignment) {
17110 for (
FieldDecl *FDI : ReverseMemberChain) {
17111 if (FDI->hasAttr<PackedAttr>() ||
17112 FDI->getParent()->hasAttr<PackedAttr>()) {
17114 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
17120 assert(FD &&
"We did not find a packed FieldDecl!");
17121 Action(E, FD->
getParent(), FD, Alignment);
17125void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
17126 using namespace std::placeholders;
17129 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
17153bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
17154 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17181 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17198 assert(!Args.empty() &&
"Should have at least one argument.");
17200 Expr *Arg0 = Args.front();
17203 auto EmitError = [&](
Expr *ArgI) {
17205 diag::err_typecheck_call_different_arg_types)
17206 << Arg0->
getType() << ArgI->getType();
17211 for (
Expr *ArgI : Args.drop_front())
17222 for (
Expr *ArgI : Args.drop_front()) {
17223 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17226 VecI->getElementType()) ||
17227 Vec0->getNumElements() != VecI->getNumElements()) {
17236std::optional<QualType>
17240 return std::nullopt;
17244 return std::nullopt;
17247 for (
int I = 0; I < 2; ++I) {
17251 return std::nullopt;
17252 Args[I] = Converted.
get();
17259 return std::nullopt;
17262 return std::nullopt;
17264 TheCall->
setArg(0, Args[0]);
17265 TheCall->
setArg(1, Args[1]);
17276 TheCall->
getArg(1), Loc) ||
17278 TheCall->
getArg(2), Loc))
17282 for (
int I = 0; I < 3; ++I) {
17287 Args[I] = Converted.
get();
17290 int ArgOrdinal = 1;
17291 for (
Expr *Arg : Args) {
17293 ArgTyRestr, ArgOrdinal++))
17300 for (
int I = 0; I < 3; ++I)
17301 TheCall->
setArg(I, Args[I]);
17307bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17319bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17328 diag::err_builtin_invalid_arg_type)
17329 << 1 << 2 << 1 << 1 << TyArg;
17343 Expr *Matrix = MatrixArg.
get();
17345 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17348 << 1 << 3 << 0 << 0
17355 QualType ResultType =
Context.getConstantMatrixType(
17356 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17359 TheCall->
setType(ResultType);
17362 TheCall->
setArg(0, Matrix);
17367static std::optional<unsigned>
17375 uint64_t
Dim =
Value->getZExtValue();
17391 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17393 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17401 unsigned PtrArgIdx = 0;
17402 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17403 Expr *RowsExpr = TheCall->
getArg(1);
17404 Expr *ColumnsExpr = TheCall->
getArg(2);
17405 Expr *StrideExpr = TheCall->
getArg(3);
17407 bool ArgError =
false;
17414 PtrExpr = PtrConv.
get();
17415 TheCall->
setArg(0, PtrExpr);
17422 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17423 QualType ElementTy;
17426 << PtrArgIdx + 1 << 0 << 5 << 0
17430 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17434 << PtrArgIdx + 1 << 0 << 5
17441 auto ApplyArgumentConversions = [
this](Expr *E) {
17450 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17452 RowsExpr = RowsConv.
get();
17453 TheCall->
setArg(1, RowsExpr);
17455 RowsExpr =
nullptr;
17457 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17459 ColumnsExpr = ColumnsConv.
get();
17460 TheCall->
setArg(2, ColumnsExpr);
17462 ColumnsExpr =
nullptr;
17473 std::optional<unsigned> MaybeRows;
17477 std::optional<unsigned> MaybeColumns;
17482 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17485 StrideExpr = StrideConv.
get();
17486 TheCall->
setArg(3, StrideExpr);
17489 if (std::optional<llvm::APSInt>
Value =
17492 if (Stride < *MaybeRows) {
17494 diag::err_builtin_matrix_stride_too_small);
17500 if (ArgError || !MaybeRows || !MaybeColumns)
17504 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17515 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17517 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17525 unsigned PtrArgIdx = 1;
17526 Expr *MatrixExpr = TheCall->
getArg(0);
17527 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17528 Expr *StrideExpr = TheCall->
getArg(2);
17530 bool ArgError =
false;
17536 MatrixExpr = MatrixConv.
get();
17537 TheCall->
setArg(0, MatrixExpr);
17544 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17547 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17555 PtrExpr = PtrConv.
get();
17556 TheCall->
setArg(1, PtrExpr);
17564 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17567 << PtrArgIdx + 1 << 0 << 5 << 0
17571 QualType ElementTy = PtrTy->getPointeeType();
17573 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17578 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17580 diag::err_builtin_matrix_pointer_arg_mismatch)
17581 << ElementTy << MatrixTy->getElementType();
17596 StrideExpr = StrideConv.
get();
17597 TheCall->
setArg(2, StrideExpr);
17602 if (std::optional<llvm::APSInt>
Value =
17605 if (Stride < MatrixTy->getNumRows()) {
17607 diag::err_builtin_matrix_stride_too_small);
17627 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17632 llvm::StringSet<> CalleeTCBs;
17633 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17634 CalleeTCBs.insert(A->getTCBName());
17635 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17636 CalleeTCBs.insert(A->getTCBName());
17640 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17641 StringRef CallerTCB = A->getTCBName();
17642 if (CalleeTCBs.count(CallerTCB) == 0) {
17643 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17644 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
Defines enumerations for traits support.
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
llvm::MachO::Record Record
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 getFunctionName(const CallEvent &Call)
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 ExprResult PointerAuthAuthWithPCAndResign(Sema &S, CallExpr *Call)
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 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.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
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 * getStart() const
StringRef toString() 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
Returns true if this DeclContext is a function, Objective-C method, or block, or a DeclContext that c...
DeclContext * getEnclosingNonExpansionStatementContext()
Retrieve the innermost enclosing context that doesn't belong to an expansion statement.
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 hasUnrecoverableErrorOccurred() const
Determine whether any unrecoverable 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
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ 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...
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.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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
ARM8_3Key
Hardware pointer-signing keys in ARM8.3.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
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(const TargetInfo &TI, 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 convertArgumentToType(Expr *&Value, QualType Ty)
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.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
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
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 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 isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
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 isAnyComplexType() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
bool 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)
SetTy< T > join(SetTy< T > A, SetTy< T > B, typename SetTy< T >::Factory &F)
Computes the union of two ImmutableSets.
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ Success
Annotation was successful.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
bool isFunctionOrMethodVariadic(const Decl *D)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
unsigned 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.