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;
1188 assert(
Integer.isUnsigned() &&
1189 "size arg should be unsigned after implicit conversion to size_t");
1193 std::optional<llvm::APSInt> ComputeSizeArgument(
unsigned Index) {
1199 if (Index < FD->getNumParams()) {
1200 if (
const auto *POS =
1202 BOSType = POS->getType();
1205 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1207 return std::nullopt;
1208 unsigned NewIndex = *IndexOptional;
1211 return std::nullopt;
1213 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1214 if (std::optional<uint64_t> ObjSize =
1217 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1219 return std::nullopt;
1222 std::optional<llvm::APSInt> ComputeStrLenArgument(
unsigned Index) {
1223 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1225 return std::nullopt;
1226 unsigned NewIndex = *IndexOptional;
1228 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1230 if (std::optional<uint64_t>
Result =
1233 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1235 return std::nullopt;
1238 unsigned getSizeTypeWidth()
const {
return SizeTypeWidth; }
1240 unsigned getBuiltinID()
const {
1241 const FunctionDecl *UseDecl = FD;
1243 UseDecl = DABAttr->getFunction();
1244 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1251 unsigned ID = getBuiltinID();
1255 assert(Callee &&
"expected callee");
1256 return Callee->getName().str();
1259 StringRef Ref = Name;
1261 if (!(Ref.consume_front(
"__builtin___") && Ref.consume_back(
"_chk")))
1262 Ref.consume_front(
"__builtin_");
1263 assert(!Ref.empty() &&
"expected non-empty function name");
1268 void checkSourceOverread(
unsigned SrcArgIdx,
unsigned SizeArgIdx) {
1272 const Expr *SrcArg = TheCall->
getArg(SrcArgIdx);
1273 const Expr *SizeArg = TheCall->
getArg(SizeArgIdx);
1278 std::optional<llvm::APSInt> CopyLen =
1279 ComputeExplicitObjectSizeArgument(SizeArgIdx);
1280 std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx);
1282 if (!CopyLen || !SrcBufSize)
1286 if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0)
1290 S.
PDiag(diag::warn_stringop_overread)
1292 << SrcBufSize->getZExtValue());
1299 const DiagnoseAsBuiltinAttr *DABAttr;
1300 unsigned SizeTypeWidth;
1304void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1309 FortifiedBufferChecker Checker(*
this, FD, TheCall);
1311 unsigned BuiltinID = Checker.getBuiltinID();
1315 unsigned SizeTypeWidth = Checker.getSizeTypeWidth();
1317 std::optional<llvm::APSInt> SourceSize;
1318 std::optional<llvm::APSInt> DestinationSize;
1319 unsigned DiagID = 0;
1321 switch (BuiltinID) {
1324 case Builtin::BI__builtin_strcat:
1325 case Builtin::BIstrcat:
1326 case Builtin::BI__builtin_stpcpy:
1327 case Builtin::BIstpcpy:
1328 case Builtin::BI__builtin_strcpy:
1329 case Builtin::BIstrcpy: {
1330 DiagID = diag::warn_fortify_strlen_overflow;
1331 SourceSize = Checker.ComputeStrLenArgument(1);
1332 DestinationSize = Checker.ComputeSizeArgument(0);
1336 case Builtin::BI__builtin___strcat_chk:
1337 case Builtin::BI__builtin___stpcpy_chk:
1338 case Builtin::BI__builtin___strcpy_chk: {
1339 DiagID = diag::warn_fortify_strlen_overflow;
1340 SourceSize = Checker.ComputeStrLenArgument(1);
1341 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1345 case Builtin::BIscanf:
1346 case Builtin::BIfscanf:
1347 case Builtin::BIsscanf: {
1348 unsigned FormatIndex = 1;
1349 unsigned DataIndex = 2;
1350 if (BuiltinID == Builtin::BIscanf) {
1355 const auto *FormatExpr =
1358 StringRef FormatStrRef;
1363 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1364 unsigned SourceSize) {
1365 DiagID = diag::warn_fortify_scanf_overflow;
1366 unsigned Index = ArgIndex + DataIndex;
1367 std::string FunctionName = Checker.getFunctionName();
1369 PDiag(DiagID) << FunctionName << (Index + 1)
1370 << DestSize << SourceSize);
1373 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1374 return Checker.ComputeSizeArgument(Index + DataIndex);
1376 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1377 const char *FormatBytes = FormatStrRef.data();
1388 case Builtin::BIsprintf:
1389 case Builtin::BI__builtin___sprintf_chk: {
1390 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1393 StringRef FormatStrRef;
1396 EstimateSizeFormatHandler H(FormatStrRef);
1397 const char *FormatBytes = FormatStrRef.data();
1399 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1400 Context.getTargetInfo(),
false)) {
1401 DiagID = H.isKernelCompatible()
1402 ? diag::warn_format_overflow
1403 : diag::warn_format_overflow_non_kprintf;
1404 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1405 .extOrTrunc(SizeTypeWidth);
1406 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1407 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1409 DestinationSize = Checker.ComputeSizeArgument(0);
1416 case Builtin::BI__builtin___memcpy_chk:
1417 case Builtin::BI__builtin___memmove_chk:
1418 case Builtin::BI__builtin___memset_chk:
1419 case Builtin::BI__builtin___strlcat_chk:
1420 case Builtin::BI__builtin___strlcpy_chk:
1421 case Builtin::BI__builtin___strncat_chk:
1422 case Builtin::BI__builtin___strncpy_chk:
1423 case Builtin::BI__builtin___stpncpy_chk:
1424 case Builtin::BI__builtin___memccpy_chk:
1425 case Builtin::BI__builtin___mempcpy_chk: {
1426 DiagID = diag::warn_builtin_chk_overflow;
1428 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1430 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1432 if (BuiltinID == Builtin::BI__builtin___memcpy_chk ||
1433 BuiltinID == Builtin::BI__builtin___memmove_chk ||
1434 BuiltinID == Builtin::BI__builtin___mempcpy_chk) {
1435 Checker.checkSourceOverread(1, 2);
1440 case Builtin::BI__builtin___snprintf_chk:
1441 case Builtin::BI__builtin___vsnprintf_chk: {
1442 DiagID = diag::warn_builtin_chk_overflow;
1443 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1444 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(3);
1448 case Builtin::BIstrncat:
1449 case Builtin::BI__builtin_strncat:
1450 case Builtin::BIstrncpy:
1451 case Builtin::BI__builtin_strncpy:
1452 case Builtin::BIstpncpy:
1453 case Builtin::BI__builtin_stpncpy:
1454 case Builtin::BIstrlcat:
1455 case Builtin::BI__builtin_strlcat: {
1461 DiagID = diag::warn_fortify_source_size_mismatch;
1463 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1464 DestinationSize = Checker.ComputeSizeArgument(0);
1468 case Builtin::BIbzero:
1469 case Builtin::BI__builtin_bzero:
1470 case Builtin::BImemcpy:
1471 case Builtin::BI__builtin_memcpy:
1472 case Builtin::BImemmove:
1473 case Builtin::BI__builtin_memmove:
1474 case Builtin::BImemset:
1475 case Builtin::BI__builtin_memset:
1476 case Builtin::BImempcpy:
1477 case Builtin::BI__builtin_mempcpy: {
1478 DiagID = diag::warn_fortify_source_overflow;
1480 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1481 DestinationSize = Checker.ComputeSizeArgument(0);
1484 if (BuiltinID != Builtin::BImemset &&
1485 BuiltinID != Builtin::BI__builtin_memset &&
1486 BuiltinID != Builtin::BIbzero &&
1487 BuiltinID != Builtin::BI__builtin_bzero) {
1488 Checker.checkSourceOverread(1, 2);
1492 case Builtin::BIbcopy:
1493 case Builtin::BI__builtin_bcopy: {
1494 DiagID = diag::warn_fortify_source_overflow;
1496 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1497 DestinationSize = Checker.ComputeSizeArgument(1);
1498 Checker.checkSourceOverread(0, 2);
1503 case Builtin::BImemchr:
1504 case Builtin::BI__builtin_memchr: {
1505 Checker.checkSourceOverread(0, 2);
1511 case Builtin::BImemcmp:
1512 case Builtin::BI__builtin_memcmp:
1513 case Builtin::BIbcmp:
1514 case Builtin::BI__builtin_bcmp: {
1515 Checker.checkSourceOverread(0, 2);
1516 Checker.checkSourceOverread(1, 2);
1519 case Builtin::BIsnprintf:
1520 case Builtin::BI__builtin_snprintf:
1521 case Builtin::BIvsnprintf:
1522 case Builtin::BI__builtin_vsnprintf: {
1523 DiagID = diag::warn_fortify_source_size_mismatch;
1524 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1526 StringRef FormatStrRef;
1530 EstimateSizeFormatHandler H(FormatStrRef);
1531 const char *FormatBytes = FormatStrRef.data();
1533 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1534 Context.getTargetInfo(),
false)) {
1535 llvm::APSInt FormatSize =
1536 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1537 .extOrTrunc(SizeTypeWidth);
1538 if (FormatSize > *SourceSize && *SourceSize != 0) {
1539 unsigned TruncationDiagID =
1540 H.isKernelCompatible() ? diag::warn_format_truncation
1541 : diag::warn_format_truncation_non_kprintf;
1542 SmallString<16> SpecifiedSizeStr;
1543 SmallString<16> FormatSizeStr;
1544 SourceSize->toString(SpecifiedSizeStr, 10);
1545 FormatSize.toString(FormatSizeStr, 10);
1547 PDiag(TruncationDiagID)
1548 << Checker.getFunctionName()
1549 << SpecifiedSizeStr << FormatSizeStr);
1553 DestinationSize = Checker.ComputeSizeArgument(0);
1557 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1561 if (!SourceSize || !DestinationSize ||
1562 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1565 std::string FunctionName = Checker.getFunctionName();
1567 SmallString<16> DestinationStr;
1568 SmallString<16> SourceStr;
1569 DestinationSize->toString(DestinationStr, 10);
1570 SourceSize->toString(SourceStr, 10);
1573 << FunctionName << DestinationStr << SourceStr);
1593 Expr *Arg = TheCall->
getArg(0);
1601 llvm::APInt RawValue =
R.Val.getInt();
1602 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1603 llvm::APInt
Extra = RawValue & ~Mask;
1606 SmallString<16> ExtraStr;
1607 Extra.toString(ExtraStr, 8,
false);
1624 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1627 << DRE->getDecl()->getIdentifier();
1639 "__builtin_alloca has invalid address space");
1665enum PointerAuthOpKind {
1681 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1712 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1715 llvm::raw_svector_ostream Str(
Value);
1724 Result = KeyValue->getZExtValue();
1743 bool IsAddrDiscArg =
false;
1748 IsAddrDiscArg =
true;
1757 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1758 <<
Result->getExtValue();
1760 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1766 IntVal =
Result->getZExtValue();
1770static std::pair<const ValueDecl *, CharUnits>
1777 const auto *BaseDecl =
1782 return {BaseDecl,
Result.Val.getLValueOffset()};
1786 bool RequireConstant =
false) {
1794 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1795 return OpKind != PAO_BlendInteger;
1797 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1798 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1799 OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
1808 }
else if (AllowsInteger(OpKind) &&
1815 <<
unsigned(OpKind == PAO_Discriminator ? 1
1816 : OpKind == PAO_BlendPointer ? 2
1817 : OpKind == PAO_BlendInteger ? 3
1818 : OpKind == PAO_BlendPC ? 4
1820 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1830 if (!RequireConstant) {
1832 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1835 ? diag::warn_ptrauth_sign_null_pointer
1836 : diag::warn_ptrauth_auth_null_pointer)
1846 if (OpKind == PAO_Sign) {
1864 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1869 assert(OpKind == PAO_Discriminator);
1875 if (
Call->getBuiltinCallee() ==
1876 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1891 assert(
Pointer->getType()->isPointerType());
1903 assert(
Integer->getType()->isIntegerType());
1909 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1922 Call->setType(
Call->getArgs()[0]->getType());
1953 PointerAuthOpKind OpKind,
1954 bool RequireConstant) {
1965 Call->setType(
Call->getArgs()[0]->getType());
1981 Call->setType(
Call->getArgs()[0]->getType());
2002 unsigned OldKey = 0;
2005 if (OldKey !=
static_cast<unsigned>(AK::ASIA) &&
2006 OldKey !=
static_cast<unsigned>(AK::ASIB)) {
2007 S.
Diag(
Call->getArgs()[1]->getExprLoc(),
2008 diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
2009 << OldKey <<
Call->getArgs()[1]->getSourceRange();
2014 Call->setType(
Call->getArgs()[0]->getType());
2023 const Expr *AddendExpr =
Call->getArg(5);
2025 if (!AddendIsConstInt) {
2026 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
2040 Call->setType(
Call->getArgs()[0]->getType());
2049 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
2052 const auto *Literal = dyn_cast<StringLiteral>(Arg);
2053 if (!Literal || Literal->getCharByteWidth() != 1) {
2069 Call->setArg(0, FirstValue.
get());
2075 if (!FirstArgRecord) {
2076 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2077 << 0 << FirstArgType;
2082 diag::err_get_vtable_pointer_requires_complete_type)) {
2087 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2088 << 1 << FirstArgRecord;
2092 Call->setType(ReturnType);
2117 auto DiagSelect = [&]() -> std::optional<unsigned> {
2124 return std::optional<unsigned>{};
2139 diag::err_incomplete_type))
2143 "Unhandled non-object pointer case");
2171 if (PT->getPointeeType()->isFunctionType()) {
2173 diag::err_builtin_is_within_lifetime_invalid_arg)
2179 if (PT->getPointeeType()->isVariableArrayType()) {
2181 << 1 <<
"__builtin_is_within_lifetime";
2186 diag::err_builtin_is_within_lifetime_invalid_arg)
2200 diag::err_builtin_trivially_relocate_invalid_arg_type)
2207 diag::err_incomplete_type))
2211 T->isIncompleteArrayType()) {
2213 diag::err_builtin_trivially_relocate_invalid_arg_type)
2214 << (
T.isConstQualified() ? 1 : 2);
2223 diag::err_builtin_trivially_relocate_invalid_arg_type)
2230 if (Size.isInvalid())
2234 if (Size.isInvalid())
2236 SizeExpr = Size.get();
2237 TheCall->
setArg(2, SizeExpr);
2247 llvm::Triple::ObjectFormatType CurObjFormat =
2249 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2262 llvm::Triple::ArchType CurArch =
2264 if (llvm::is_contained(SupportedArchs, CurArch))
2274bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2281 case llvm::Triple::arm:
2282 case llvm::Triple::armeb:
2283 case llvm::Triple::thumb:
2284 case llvm::Triple::thumbeb:
2286 case llvm::Triple::aarch64:
2287 case llvm::Triple::aarch64_32:
2288 case llvm::Triple::aarch64_be:
2290 case llvm::Triple::bpfeb:
2291 case llvm::Triple::bpfel:
2293 case llvm::Triple::dxil:
2295 case llvm::Triple::hexagon:
2297 case llvm::Triple::mips:
2298 case llvm::Triple::mipsel:
2299 case llvm::Triple::mips64:
2300 case llvm::Triple::mips64el:
2302 case llvm::Triple::spirv:
2303 case llvm::Triple::spirv32:
2304 case llvm::Triple::spirv64:
2305 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2308 case llvm::Triple::systemz:
2310 case llvm::Triple::x86:
2311 case llvm::Triple::x86_64:
2313 case llvm::Triple::ppc:
2314 case llvm::Triple::ppcle:
2315 case llvm::Triple::ppc64:
2316 case llvm::Triple::ppc64le:
2318 case llvm::Triple::amdgpu:
2320 case llvm::Triple::riscv32:
2321 case llvm::Triple::riscv64:
2322 case llvm::Triple::riscv32be:
2323 case llvm::Triple::riscv64be:
2325 case llvm::Triple::loongarch32:
2326 case llvm::Triple::loongarch64:
2329 case llvm::Triple::wasm32:
2330 case llvm::Triple::wasm64:
2332 case llvm::Triple::nvptx:
2333 case llvm::Triple::nvptx64:
2339 return T->isDependentType() ||
2340 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2355 switch (ArgTyRestr) {
2359 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2360 << ArgOrdinal << 2 << 1 << 1
2367 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2368 << ArgOrdinal << 5 << 0
2374 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2375 << ArgOrdinal << 5 << 1
2381 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2395 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2396 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2397 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2398 "Expecting __builtin_cpu_...");
2400 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2402 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2403 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2404 (!IsCPUSupports && TInfo->supportsCpuIs()));
2406 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2413 ? diag::err_builtin_aix_os_unsupported
2414 : diag::err_builtin_target_unsupported)
2420 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2458 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2459 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2460 BT->getNumBits() != 1) {
2462 << ArgTy << BT->getNumBits();
2538 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2541 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2550 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2551 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2571 TheCall->
setArg(0, Arg0);
2588 TheCall->
setArg(1, Arg1);
2594 << 2 << 1 << 4 << 0 << Arg1Ty;
2608 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2610 << (OnlyUnsigned ? 3 : 1)
2618 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2621 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2626 return emitError(S, Loc,
T);
2631 return emitError(S, Loc,
T);
2637 return emitError(S, Loc,
T);
2642 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2647 return emitError(S, Loc,
T);
2652 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2658 llvm_unreachable(
"conversion functions are permitted");
2677 TheCall->
setArg(0, Arg0);
2691 TheCall->
setArg(1, Arg1);
2702 unsigned Pos,
bool AllowConst,
2706 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2711 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2712 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2713 << Pos <<
"scalar pointer";
2722 diag::err_typecheck_convert_incompatible)
2731 bool TypeDependent =
false;
2732 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2760 Builtin::BI__builtin_masked_load))
2774 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2797 Builtin::BI__builtin_masked_store))
2805 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2816 << MaskTy << ValTy);
2820 PtrTy->getPointeeType().getUnqualifiedType()))
2822 diag::err_vec_builtin_incompatible_vector)
2851 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2864 << MaskTy << IdxTy);
2873 diag::err_vec_masked_load_store_ptr)
2902 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2917 << MaskTy << IdxTy);
2923 << MaskTy << ValTy);
2926 PtrTy->getPointeeType().getUnqualifiedType()))
2928 diag::err_vec_builtin_incompatible_vector)
2942 if (Args.size() == 0) {
2944 diag::err_typecheck_call_too_few_args_at_least)
2950 QualType FuncT = Args[0]->getType();
2953 if (Args.size() < 2) {
2955 diag::err_typecheck_call_too_few_args_at_least)
2961 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2962 QualType ObjectT = Args[1]->getType();
2964 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
3013 tok::periodstar, ObjectArg.
get(), Args[0]);
3017 if (MPT->isMemberDataPointer())
3021 auto *MemCall =
new (S.
Context)
3045 return TyA->getElementType();
3052Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
3057 unsigned ICEArguments = 0;
3059 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
3064 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
3066 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
3071 if (ArgNo < TheCall->getNumArgs() &&
3074 ICEArguments &= ~(1 << ArgNo);
3078 switch (BuiltinID) {
3079 case Builtin::BI__builtin___get_unsafe_stack_start:
3080 case Builtin::BI__builtin___get_unsafe_stack_bottom:
3082 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3083 <<
"__safestack_get_unsafe_stack_bottom";
3085 case Builtin::BI__builtin___get_unsafe_stack_top:
3087 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3088 <<
"__safestack_get_unsafe_stack_top";
3090 case Builtin::BI__builtin___get_unsafe_stack_ptr:
3092 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3093 <<
"__safestack_get_unsafe_stack_ptr";
3095 case Builtin::BI__builtin_cpu_supports:
3096 case Builtin::BI__builtin_cpu_is:
3098 Context.getAuxTargetInfo(), BuiltinID))
3101 case Builtin::BI__builtin_cpu_init:
3102 if (!
Context.getTargetInfo().supportsCpuInit()) {
3108 case Builtin::BI__builtin___CFStringMakeConstantString:
3112 *
this, BuiltinID, TheCall,
3113 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
3116 "Wrong # arguments to builtin CFStringMakeConstantString");
3117 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3120 case Builtin::BI__builtin_ms_va_start:
3121 case Builtin::BI__builtin_zos_va_start:
3122 case Builtin::BI__builtin_stdarg_start:
3123 case Builtin::BI__builtin_va_start:
3124 case Builtin::BI__builtin_c23_va_start:
3125 if (BuiltinVAStart(BuiltinID, TheCall))
3128 case Builtin::BI__va_start: {
3129 switch (
Context.getTargetInfo().getTriple().getArch()) {
3130 case llvm::Triple::aarch64:
3131 case llvm::Triple::arm:
3132 case llvm::Triple::thumb:
3133 if (BuiltinVAStartARMMicrosoft(TheCall))
3137 if (BuiltinVAStart(BuiltinID, TheCall))
3145 case Builtin::BI_interlockedbittestandset_acq:
3146 case Builtin::BI_interlockedbittestandset_rel:
3147 case Builtin::BI_interlockedbittestandset_nf:
3148 case Builtin::BI_interlockedbittestandreset_acq:
3149 case Builtin::BI_interlockedbittestandreset_rel:
3150 case Builtin::BI_interlockedbittestandreset_nf:
3153 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3158 case Builtin::BI_bittest64:
3159 case Builtin::BI_bittestandcomplement64:
3160 case Builtin::BI_bittestandreset64:
3161 case Builtin::BI_bittestandset64:
3162 case Builtin::BI_interlockedbittestandreset64:
3163 case Builtin::BI_interlockedbittestandset64:
3166 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3167 llvm::Triple::aarch64, llvm::Triple::amdgpu}))
3172 case Builtin::BI_interlockedbittestandreset64_acq:
3173 case Builtin::BI_interlockedbittestandreset64_rel:
3174 case Builtin::BI_interlockedbittestandreset64_nf:
3175 case Builtin::BI_interlockedbittestandset64_acq:
3176 case Builtin::BI_interlockedbittestandset64_rel:
3177 case Builtin::BI_interlockedbittestandset64_nf:
3182 case Builtin::BI__builtin_set_flt_rounds:
3185 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3186 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgpu,
3187 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3188 llvm::Triple::ppc64le}))
3192 case Builtin::BI__builtin_isgreater:
3193 case Builtin::BI__builtin_isgreaterequal:
3194 case Builtin::BI__builtin_isless:
3195 case Builtin::BI__builtin_islessequal:
3196 case Builtin::BI__builtin_islessgreater:
3197 case Builtin::BI__builtin_isunordered:
3198 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3201 case Builtin::BI__builtin_fpclassify:
3202 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3205 case Builtin::BI__builtin_isfpclass:
3206 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3209 case Builtin::BI__builtin_isfinite:
3210 case Builtin::BI__builtin_isinf:
3211 case Builtin::BI__builtin_isinf_sign:
3212 case Builtin::BI__builtin_isnan:
3213 case Builtin::BI__builtin_issignaling:
3214 case Builtin::BI__builtin_isnormal:
3215 case Builtin::BI__builtin_issubnormal:
3216 case Builtin::BI__builtin_iszero:
3217 case Builtin::BI__builtin_signbit:
3218 case Builtin::BI__builtin_signbitf:
3219 case Builtin::BI__builtin_signbitl:
3220 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3223 case Builtin::BI__builtin_shufflevector:
3227 case Builtin::BI__builtin_masked_load:
3228 case Builtin::BI__builtin_masked_expand_load:
3230 case Builtin::BI__builtin_masked_store:
3231 case Builtin::BI__builtin_masked_compress_store:
3233 case Builtin::BI__builtin_masked_gather:
3235 case Builtin::BI__builtin_masked_scatter:
3237 case Builtin::BI__builtin_invoke:
3239 case Builtin::BI__builtin_prefetch:
3240 if (BuiltinPrefetch(TheCall))
3243 case Builtin::BI__builtin_alloca_with_align:
3244 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3245 if (BuiltinAllocaWithAlign(TheCall))
3248 case Builtin::BI__builtin_alloca:
3249 case Builtin::BI__builtin_alloca_uninitialized:
3256 case Builtin::BI__builtin_infer_alloc_token:
3260 case Builtin::BI__arithmetic_fence:
3261 if (BuiltinArithmeticFence(TheCall))
3264 case Builtin::BI__assume:
3265 case Builtin::BI__builtin_assume:
3266 if (BuiltinAssume(TheCall))
3269 case Builtin::BI__builtin_assume_aligned:
3270 if (BuiltinAssumeAligned(TheCall))
3273 case Builtin::BI__builtin_dynamic_object_size:
3274 case Builtin::BI__builtin_object_size:
3278 case Builtin::BI__builtin_longjmp:
3279 if (BuiltinLongjmp(TheCall))
3282 case Builtin::BI__builtin_setjmp:
3283 if (BuiltinSetjmp(TheCall))
3286 case Builtin::BI__builtin_complex:
3287 if (BuiltinComplex(TheCall))
3290 case Builtin::BI__builtin_classify_type:
3291 case Builtin::BI__builtin_constant_p: {
3300 case Builtin::BI__builtin_launder:
3302 case Builtin::BI__builtin_is_within_lifetime:
3304 case Builtin::BI__builtin_trivially_relocate:
3306 case Builtin::BI__builtin_clear_padding: {
3310 const Expr *PtrArg = TheCall->
getArg(0);
3311 const QualType PtrArgType = PtrArg->
getType();
3314 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3325 diag::err_typecheck_decl_incomplete_type))
3331 auto IsAddrOfDeclExpr = [&]() {
3333 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3334 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3338 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3339 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3343 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3344 if (!VarDecl || VarDecl->getType()->isReferenceType())
3349 QualType VarQType = VarDecl->getType();
3351 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3356 && !IsAddrOfDeclExpr()) {
3357 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3364 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3371 case Builtin::BI__sync_fetch_and_add:
3372 case Builtin::BI__sync_fetch_and_add_1:
3373 case Builtin::BI__sync_fetch_and_add_2:
3374 case Builtin::BI__sync_fetch_and_add_4:
3375 case Builtin::BI__sync_fetch_and_add_8:
3376 case Builtin::BI__sync_fetch_and_add_16:
3377 case Builtin::BI__sync_fetch_and_sub:
3378 case Builtin::BI__sync_fetch_and_sub_1:
3379 case Builtin::BI__sync_fetch_and_sub_2:
3380 case Builtin::BI__sync_fetch_and_sub_4:
3381 case Builtin::BI__sync_fetch_and_sub_8:
3382 case Builtin::BI__sync_fetch_and_sub_16:
3383 case Builtin::BI__sync_fetch_and_or:
3384 case Builtin::BI__sync_fetch_and_or_1:
3385 case Builtin::BI__sync_fetch_and_or_2:
3386 case Builtin::BI__sync_fetch_and_or_4:
3387 case Builtin::BI__sync_fetch_and_or_8:
3388 case Builtin::BI__sync_fetch_and_or_16:
3389 case Builtin::BI__sync_fetch_and_and:
3390 case Builtin::BI__sync_fetch_and_and_1:
3391 case Builtin::BI__sync_fetch_and_and_2:
3392 case Builtin::BI__sync_fetch_and_and_4:
3393 case Builtin::BI__sync_fetch_and_and_8:
3394 case Builtin::BI__sync_fetch_and_and_16:
3395 case Builtin::BI__sync_fetch_and_xor:
3396 case Builtin::BI__sync_fetch_and_xor_1:
3397 case Builtin::BI__sync_fetch_and_xor_2:
3398 case Builtin::BI__sync_fetch_and_xor_4:
3399 case Builtin::BI__sync_fetch_and_xor_8:
3400 case Builtin::BI__sync_fetch_and_xor_16:
3401 case Builtin::BI__sync_fetch_and_nand:
3402 case Builtin::BI__sync_fetch_and_nand_1:
3403 case Builtin::BI__sync_fetch_and_nand_2:
3404 case Builtin::BI__sync_fetch_and_nand_4:
3405 case Builtin::BI__sync_fetch_and_nand_8:
3406 case Builtin::BI__sync_fetch_and_nand_16:
3407 case Builtin::BI__sync_add_and_fetch:
3408 case Builtin::BI__sync_add_and_fetch_1:
3409 case Builtin::BI__sync_add_and_fetch_2:
3410 case Builtin::BI__sync_add_and_fetch_4:
3411 case Builtin::BI__sync_add_and_fetch_8:
3412 case Builtin::BI__sync_add_and_fetch_16:
3413 case Builtin::BI__sync_sub_and_fetch:
3414 case Builtin::BI__sync_sub_and_fetch_1:
3415 case Builtin::BI__sync_sub_and_fetch_2:
3416 case Builtin::BI__sync_sub_and_fetch_4:
3417 case Builtin::BI__sync_sub_and_fetch_8:
3418 case Builtin::BI__sync_sub_and_fetch_16:
3419 case Builtin::BI__sync_and_and_fetch:
3420 case Builtin::BI__sync_and_and_fetch_1:
3421 case Builtin::BI__sync_and_and_fetch_2:
3422 case Builtin::BI__sync_and_and_fetch_4:
3423 case Builtin::BI__sync_and_and_fetch_8:
3424 case Builtin::BI__sync_and_and_fetch_16:
3425 case Builtin::BI__sync_or_and_fetch:
3426 case Builtin::BI__sync_or_and_fetch_1:
3427 case Builtin::BI__sync_or_and_fetch_2:
3428 case Builtin::BI__sync_or_and_fetch_4:
3429 case Builtin::BI__sync_or_and_fetch_8:
3430 case Builtin::BI__sync_or_and_fetch_16:
3431 case Builtin::BI__sync_xor_and_fetch:
3432 case Builtin::BI__sync_xor_and_fetch_1:
3433 case Builtin::BI__sync_xor_and_fetch_2:
3434 case Builtin::BI__sync_xor_and_fetch_4:
3435 case Builtin::BI__sync_xor_and_fetch_8:
3436 case Builtin::BI__sync_xor_and_fetch_16:
3437 case Builtin::BI__sync_nand_and_fetch:
3438 case Builtin::BI__sync_nand_and_fetch_1:
3439 case Builtin::BI__sync_nand_and_fetch_2:
3440 case Builtin::BI__sync_nand_and_fetch_4:
3441 case Builtin::BI__sync_nand_and_fetch_8:
3442 case Builtin::BI__sync_nand_and_fetch_16:
3443 case Builtin::BI__sync_val_compare_and_swap:
3444 case Builtin::BI__sync_val_compare_and_swap_1:
3445 case Builtin::BI__sync_val_compare_and_swap_2:
3446 case Builtin::BI__sync_val_compare_and_swap_4:
3447 case Builtin::BI__sync_val_compare_and_swap_8:
3448 case Builtin::BI__sync_val_compare_and_swap_16:
3449 case Builtin::BI__sync_bool_compare_and_swap:
3450 case Builtin::BI__sync_bool_compare_and_swap_1:
3451 case Builtin::BI__sync_bool_compare_and_swap_2:
3452 case Builtin::BI__sync_bool_compare_and_swap_4:
3453 case Builtin::BI__sync_bool_compare_and_swap_8:
3454 case Builtin::BI__sync_bool_compare_and_swap_16:
3455 case Builtin::BI__sync_lock_test_and_set:
3456 case Builtin::BI__sync_lock_test_and_set_1:
3457 case Builtin::BI__sync_lock_test_and_set_2:
3458 case Builtin::BI__sync_lock_test_and_set_4:
3459 case Builtin::BI__sync_lock_test_and_set_8:
3460 case Builtin::BI__sync_lock_test_and_set_16:
3461 case Builtin::BI__sync_lock_release:
3462 case Builtin::BI__sync_lock_release_1:
3463 case Builtin::BI__sync_lock_release_2:
3464 case Builtin::BI__sync_lock_release_4:
3465 case Builtin::BI__sync_lock_release_8:
3466 case Builtin::BI__sync_lock_release_16:
3467 case Builtin::BI__sync_swap:
3468 case Builtin::BI__sync_swap_1:
3469 case Builtin::BI__sync_swap_2:
3470 case Builtin::BI__sync_swap_4:
3471 case Builtin::BI__sync_swap_8:
3472 case Builtin::BI__sync_swap_16:
3473 return BuiltinAtomicOverloaded(TheCallResult);
3474 case Builtin::BI__sync_synchronize:
3478 case Builtin::BI__builtin_nontemporal_load:
3479 case Builtin::BI__builtin_nontemporal_store:
3480 return BuiltinNontemporalOverloaded(TheCallResult);
3481 case Builtin::BI__builtin_memcpy_inline: {
3482 clang::Expr *SizeOp = TheCall->
getArg(2);
3494 case Builtin::BI__builtin_memset_inline: {
3495 clang::Expr *SizeOp = TheCall->
getArg(2);
3505#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3506 case Builtin::BI##ID: \
3507 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3508#include "clang/Basic/Builtins.inc"
3509 case Builtin::BI__annotation: {
3510 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3511 if (!TT.isOSWindows() && !TT.isUEFI()) {
3520 case Builtin::BI__builtin_annotation:
3524 case Builtin::BI__builtin_addressof:
3528 case Builtin::BI__builtin_function_start:
3532 case Builtin::BI__builtin_is_aligned:
3533 case Builtin::BI__builtin_align_up:
3534 case Builtin::BI__builtin_align_down:
3538 case Builtin::BI__builtin_add_overflow:
3539 case Builtin::BI__builtin_sub_overflow:
3540 case Builtin::BI__builtin_mul_overflow:
3544 case Builtin::BI__builtin_operator_new:
3545 case Builtin::BI__builtin_operator_delete: {
3546 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3548 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3551 case Builtin::BI__builtin_dump_struct:
3553 case Builtin::BI__builtin_expect_with_probability: {
3558 const Expr *ProbArg = TheCall->
getArg(2);
3559 SmallVector<PartialDiagnosticAt, 8> Notes;
3560 Expr::EvalResult Eval;
3564 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3571 bool LoseInfo =
false;
3572 Probability.convert(llvm::APFloat::IEEEdouble(),
3573 llvm::RoundingMode::Dynamic, &LoseInfo);
3574 if (!(Probability >= llvm::APFloat(0.0) &&
3575 Probability <= llvm::APFloat(1.0))) {
3582 case Builtin::BI__builtin_preserve_access_index:
3586 case Builtin::BI__builtin_call_with_static_chain:
3590 case Builtin::BI__exception_code:
3591 case Builtin::BI_exception_code:
3593 diag::err_seh___except_block))
3596 case Builtin::BI__exception_info:
3597 case Builtin::BI_exception_info:
3599 diag::err_seh___except_filter))
3602 case Builtin::BI__GetExceptionInfo:
3614 case Builtin::BIaddressof:
3615 case Builtin::BI__addressof:
3616 case Builtin::BIforward:
3617 case Builtin::BIforward_like:
3618 case Builtin::BImove:
3619 case Builtin::BImove_if_noexcept:
3620 case Builtin::BIas_const: {
3628 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3629 BuiltinID == Builtin::BI__addressof;
3631 (ReturnsPointer ?
Result->isAnyPointerType()
3632 :
Result->isReferenceType()) &&
3635 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3641 case Builtin::BI__builtin_ptrauth_strip:
3643 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3645 case Builtin::BI__builtin_ptrauth_sign_constant:
3648 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3651 case Builtin::BI__builtin_ptrauth_auth:
3654 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3656 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3658 case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
3660 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3662 case Builtin::BI__builtin_ptrauth_string_discriminator:
3665 case Builtin::BI__builtin_get_vtable_pointer:
3669 case Builtin::BIread_pipe:
3670 case Builtin::BIwrite_pipe:
3673 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3676 case Builtin::BIreserve_read_pipe:
3677 case Builtin::BIreserve_write_pipe:
3678 case Builtin::BIwork_group_reserve_read_pipe:
3679 case Builtin::BIwork_group_reserve_write_pipe:
3680 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3683 case Builtin::BIsub_group_reserve_read_pipe:
3684 case Builtin::BIsub_group_reserve_write_pipe:
3685 if (
OpenCL().checkSubgroupExt(TheCall) ||
3686 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3689 case Builtin::BIcommit_read_pipe:
3690 case Builtin::BIcommit_write_pipe:
3691 case Builtin::BIwork_group_commit_read_pipe:
3692 case Builtin::BIwork_group_commit_write_pipe:
3693 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3696 case Builtin::BIsub_group_commit_read_pipe:
3697 case Builtin::BIsub_group_commit_write_pipe:
3698 if (
OpenCL().checkSubgroupExt(TheCall) ||
3699 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3702 case Builtin::BIget_pipe_num_packets:
3703 case Builtin::BIget_pipe_max_packets:
3704 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3707 case Builtin::BIto_global:
3708 case Builtin::BIto_local:
3709 case Builtin::BIto_private:
3710 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3714 case Builtin::BIenqueue_kernel:
3715 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3718 case Builtin::BIget_kernel_work_group_size:
3719 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3720 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3723 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3724 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3725 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3728 case Builtin::BI__builtin_os_log_format:
3729 Cleanup.setExprNeedsCleanups(
true);
3731 case Builtin::BI__builtin_os_log_format_buffer_size:
3732 if (BuiltinOSLogFormat(TheCall))
3735 case Builtin::BI__builtin_frame_address:
3736 case Builtin::BI__builtin_return_address: {
3745 Result.Val.getInt() != 0)
3747 << ((BuiltinID == Builtin::BI__builtin_return_address)
3748 ?
"__builtin_return_address"
3749 :
"__builtin_frame_address")
3754 case Builtin::BI__builtin_nondeterministic_value: {
3755 if (BuiltinNonDeterministicValue(TheCall))
3762 case Builtin::BI__builtin_elementwise_abs:
3770 case Builtin::BI__builtin_elementwise_acos:
3771 case Builtin::BI__builtin_elementwise_asin:
3772 case Builtin::BI__builtin_elementwise_atan:
3773 case Builtin::BI__builtin_elementwise_ceil:
3774 case Builtin::BI__builtin_elementwise_cos:
3775 case Builtin::BI__builtin_elementwise_cosh:
3776 case Builtin::BI__builtin_elementwise_exp:
3777 case Builtin::BI__builtin_elementwise_exp2:
3778 case Builtin::BI__builtin_elementwise_exp10:
3779 case Builtin::BI__builtin_elementwise_floor:
3780 case Builtin::BI__builtin_elementwise_log:
3781 case Builtin::BI__builtin_elementwise_log2:
3782 case Builtin::BI__builtin_elementwise_log10:
3783 case Builtin::BI__builtin_elementwise_roundeven:
3784 case Builtin::BI__builtin_elementwise_round:
3785 case Builtin::BI__builtin_elementwise_rint:
3786 case Builtin::BI__builtin_elementwise_nearbyint:
3787 case Builtin::BI__builtin_elementwise_sin:
3788 case Builtin::BI__builtin_elementwise_sinh:
3789 case Builtin::BI__builtin_elementwise_sqrt:
3790 case Builtin::BI__builtin_elementwise_tan:
3791 case Builtin::BI__builtin_elementwise_tanh:
3792 case Builtin::BI__builtin_elementwise_trunc:
3793 case Builtin::BI__builtin_elementwise_canonicalize:
3798 case Builtin::BI__builtin_elementwise_fma:
3803 case Builtin::BI__builtin_elementwise_ldexp: {
3825 const auto *Vec0 = TyA->
getAs<VectorType>();
3826 const auto *Vec1 = TyExp->
getAs<VectorType>();
3827 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3829 if (Arg0Length != Arg1Length) {
3831 diag::err_typecheck_vector_lengths_not_equal)
3845 case Builtin::BI__builtin_elementwise_minnum:
3846 case Builtin::BI__builtin_elementwise_maxnum:
3847 case Builtin::BI__builtin_elementwise_minimum:
3848 case Builtin::BI__builtin_elementwise_maximum:
3849 case Builtin::BI__builtin_elementwise_minimumnum:
3850 case Builtin::BI__builtin_elementwise_maximumnum:
3851 case Builtin::BI__builtin_elementwise_atan2:
3852 case Builtin::BI__builtin_elementwise_fmod:
3853 case Builtin::BI__builtin_elementwise_pow:
3854 if (BuiltinElementwiseMath(TheCall,
3860 case Builtin::BI__builtin_elementwise_add_sat:
3861 case Builtin::BI__builtin_elementwise_sub_sat:
3862 case Builtin::BI__builtin_elementwise_clmul:
3863 case Builtin::BI__builtin_elementwise_pext:
3864 case Builtin::BI__builtin_elementwise_pdep:
3865 if (BuiltinElementwiseMath(TheCall,
3869 case Builtin::BI__builtin_elementwise_fshl:
3870 case Builtin::BI__builtin_elementwise_fshr:
3875 case Builtin::BI__builtin_elementwise_min:
3876 case Builtin::BI__builtin_elementwise_max: {
3877 if (BuiltinElementwiseMath(TheCall))
3879 Expr *Arg0 = TheCall->
getArg(0);
3880 Expr *Arg1 = TheCall->
getArg(1);
3881 QualType Ty0 = Arg0->
getType();
3882 QualType Ty1 = Arg1->
getType();
3883 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3884 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3887 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3888 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3889 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3892 case Builtin::BI__builtin_elementwise_popcount:
3893 case Builtin::BI__builtin_elementwise_bitreverse:
3898 case Builtin::BI__builtin_elementwise_copysign: {
3907 QualType MagnitudeTy = Magnitude.
get()->
getType();
3920 diag::err_typecheck_call_different_arg_types)
3921 << MagnitudeTy << SignTy;
3929 case Builtin::BI__builtin_elementwise_clzg:
3930 case Builtin::BI__builtin_elementwise_ctzg:
3938 }
else if (BuiltinElementwiseMath(
3942 case Builtin::BI__builtin_reduce_max:
3943 case Builtin::BI__builtin_reduce_min: {
3944 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3947 const Expr *Arg = TheCall->
getArg(0);
3952 ElTy = TyA->getElementType();
3956 if (ElTy.isNull()) {
3966 case Builtin::BI__builtin_reduce_maximum:
3967 case Builtin::BI__builtin_reduce_minimum: {
3968 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3971 const Expr *Arg = TheCall->
getArg(0);
3976 ElTy = TyA->getElementType();
3980 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3993 case Builtin::BI__builtin_reduce_add:
3994 case Builtin::BI__builtin_reduce_mul:
3995 case Builtin::BI__builtin_reduce_xor:
3996 case Builtin::BI__builtin_reduce_or:
3997 case Builtin::BI__builtin_reduce_and: {
3998 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4001 const Expr *Arg = TheCall->
getArg(0);
4015 case Builtin::BI__builtin_reduce_assoc_fadd:
4016 case Builtin::BI__builtin_reduce_in_order_fadd: {
4018 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
4043 diag::err_builtin_invalid_arg_type)
4055 case Builtin::BI__builtin_matrix_transpose:
4056 return BuiltinMatrixTranspose(TheCall, TheCallResult);
4058 case Builtin::BI__builtin_matrix_column_major_load:
4059 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
4061 case Builtin::BI__builtin_matrix_column_major_store:
4062 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
4064 case Builtin::BI__builtin_verbose_trap:
4069 case Builtin::BI__builtin_get_device_side_mangled_name: {
4070 auto Check = [](CallExpr *TheCall) {
4076 auto *D = DRE->getDecl();
4079 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
4080 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
4082 if (!Check(TheCall)) {
4084 diag::err_hip_invalid_args_builtin_mangled_name);
4089 case Builtin::BI__builtin_bswapg:
4093 case Builtin::BI__builtin_bitreverseg:
4097 case Builtin::BI__builtin_popcountg:
4101 case Builtin::BI__builtin_clzg:
4102 case Builtin::BI__builtin_ctzg:
4107 case Builtin::BI__builtin_stdc_rotate_left:
4108 case Builtin::BI__builtin_stdc_rotate_right:
4113 case Builtin::BI__builtin_stdc_memreverse8:
4114 case Builtin::BIstdc_memreverse8:
4115 case Builtin::BIstdc_memreverse8u8:
4116 case Builtin::BIstdc_memreverse8u16:
4117 case Builtin::BIstdc_memreverse8u32:
4118 case Builtin::BIstdc_memreverse8u64:
4119 if (
Context.getTargetInfo().getCharWidth() != 8) {
4126 case Builtin::BI__builtin_stdc_bit_floor:
4127 case Builtin::BI__builtin_stdc_bit_ceil:
4131 case Builtin::BI__builtin_stdc_has_single_bit:
4135 case Builtin::BI__builtin_stdc_leading_zeros:
4136 case Builtin::BI__builtin_stdc_leading_ones:
4137 case Builtin::BI__builtin_stdc_trailing_zeros:
4138 case Builtin::BI__builtin_stdc_trailing_ones:
4139 case Builtin::BI__builtin_stdc_first_leading_zero:
4140 case Builtin::BI__builtin_stdc_first_leading_one:
4141 case Builtin::BI__builtin_stdc_first_trailing_zero:
4142 case Builtin::BI__builtin_stdc_first_trailing_one:
4143 case Builtin::BI__builtin_stdc_count_zeros:
4144 case Builtin::BI__builtin_stdc_count_ones:
4145 case Builtin::BI__builtin_stdc_bit_width:
4150 case Builtin::BI__builtin_allow_runtime_check: {
4151 Expr *Arg = TheCall->
getArg(0);
4161 case Builtin::BI__builtin_allow_sanitize_check: {
4165 Expr *Arg = TheCall->
getArg(0);
4167 const StringLiteral *SanitizerName =
4169 if (!SanitizerName) {
4175 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4176 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4177 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4181 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4187 case Builtin::BI__builtin_counted_by_ref:
4188 if (BuiltinCountedByRef(TheCall))
4198 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4199 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4200 assert(
Context.getAuxTargetInfo() &&
4201 "Aux Target Builtin, but not an aux target?");
4203 if (CheckTSBuiltinFunctionCall(
4205 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4208 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4214 return TheCallResult;
4229 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4233 diag::err_argument_not_contiguous_bit_field)
4240 bool IsVariadic =
false;
4243 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4244 IsVariadic = BD->isVariadic();
4245 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4246 IsVariadic = OMD->isVariadic();
4253 bool HasImplicitThisParam,
bool IsVariadic,
4257 else if (IsVariadic)
4267 if (HasImplicitThisParam) {
4299 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4300 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4301 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4302 Expr = ILE->getInit(0);
4312 const Expr *ArgExpr,
4316 S.
PDiag(diag::warn_null_arg)
4322 if (
auto nullability =
type->getNullability())
4333 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4339 llvm::SmallBitVector NonNullArgs;
4345 for (
const auto *Arg : Args)
4352 unsigned IdxAST = Idx.getASTIndex();
4353 if (IdxAST >= Args.size())
4355 if (NonNullArgs.empty())
4356 NonNullArgs.resize(Args.size());
4357 NonNullArgs.set(IdxAST);
4366 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4371 unsigned ParamIndex = 0;
4373 I != E; ++I, ++ParamIndex) {
4376 if (NonNullArgs.empty())
4377 NonNullArgs.resize(Args.size());
4379 NonNullArgs.set(ParamIndex);
4386 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4391 type = blockType->getPointeeType();
4405 if (NonNullArgs.empty())
4406 NonNullArgs.resize(Args.size());
4408 NonNullArgs.set(Index);
4417 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4418 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4419 if (NonNullArgs[ArgIndex])
4425 StringRef ParamName,
QualType ArgTy,
4448 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4449 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4453 if (ArgAlign < ParamAlign)
4454 Diag(Loc, diag::warn_param_mismatched_alignment)
4456 << ParamName << (FDecl !=
nullptr) << FDecl;
4460 const Expr *ThisArg,
4462 if (!FD || Args.empty())
4464 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4465 if (Idx == LifetimeCaptureByAttr::Global ||
4466 Idx == LifetimeCaptureByAttr::Unknown)
4468 if (IsMemberFunction && Idx == 0)
4470 return Args[Idx - IsMemberFunction];
4472 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4477 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4478 for (
int CapturingParamIdx :
Attr->params()) {
4479 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4483 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4486 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4493 for (
const auto *A :
4495 HandleCaptureByAttr(A, I + IsMemberFunction);
4497 if (IsMemberFunction) {
4505 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4515 llvm::any_of(Args, [](
const Expr *E) {
4516 return E && E->isInstantiationDependent();
4521 llvm::SmallBitVector CheckedVarArgs;
4523 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4525 CheckedVarArgs.resize(Args.size());
4526 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4531 CheckedVarArgs.resize(Args.size());
4532 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4539 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4543 : isa_and_nonnull<FunctionDecl>(FDecl)
4545 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4549 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4551 if (
const Expr *Arg = Args[ArgIdx]) {
4552 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4559 if (FDecl || Proto) {
4564 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4565 CheckArgumentWithTypeTag(I, Args, Loc);
4571 if (!Proto && FDecl) {
4573 if (isa_and_nonnull<FunctionProtoType>(FT))
4579 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4581 bool IsScalableArg =
false;
4582 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4584 if (
const Expr *Arg = Args[ArgIdx]) {
4588 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4596 IsScalableArg =
true;
4598 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4607 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4608 llvm::StringMap<bool> CallerFeatureMap;
4609 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4610 if (!CallerFeatureMap.contains(
"sme"))
4611 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4612 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4613 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4622 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4624 (IsScalableArg || IsScalableRet)) {
4625 bool IsCalleeStreaming =
4627 bool IsCalleeStreamingCompatible =
4631 if (!IsCalleeStreamingCompatible &&
4635 unsigned VL = LO.VScaleMin * 128;
4636 unsigned SVL = LO.VScaleStreamingMin * 128;
4637 bool IsVLMismatch = VL && SVL && VL != SVL;
4639 auto EmitDiag = [&](
bool IsArg) {
4643 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4644 << IsArg << IsCalleeStreaming << SVL << VL;
4647 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4648 << IsArg << SVL << VL;
4650 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4667 bool CallerHasZAState =
false;
4668 bool CallerHasZT0State =
false;
4670 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4672 CallerHasZAState =
true;
4674 CallerHasZT0State =
true;
4678 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4680 CallerHasZT0State |=
4682 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4688 Diag(Loc, diag::err_sme_za_call_no_za_state);
4691 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4695 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4696 Diag(Loc, diag::note_sme_use_preserves_za);
4701 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4702 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4703 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4704 if (!Arg->isValueDependent()) {
4706 if (Arg->EvaluateAsInt(Align,
Context)) {
4707 const llvm::APSInt &I = Align.
Val.
getInt();
4708 if (!I.isPowerOf2())
4709 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4710 << Arg->getSourceRange();
4713 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4722 << diag::OffloadLang::SYCL;
4730 AutoT->getTypeConstraintConcept().getAsTemplateDecl()) {
4745 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4746 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4748 checkCall(FDecl, Proto,
nullptr, Args,
true,
4757 IsMemberOperatorCall;
4763 Expr *ImplicitThis =
nullptr;
4768 ImplicitThis = Args[0];
4771 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4782 ThisType =
Context.getPointerType(ThisType);
4788 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4806 CheckAbsoluteValueFunction(TheCall, FDecl);
4807 CheckMaxUnsignedZero(TheCall, FDecl);
4808 CheckInfNaNFunction(TheCall, FDecl);
4819 case Builtin::BIstrlcpy:
4820 case Builtin::BIstrlcat:
4821 CheckStrlcpycatArguments(TheCall, FnInfo);
4823 case Builtin::BIstrncat:
4824 CheckStrncatArguments(TheCall, FnInfo);
4826 case Builtin::BIfree:
4827 CheckFreeArguments(TheCall);
4830 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4839 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4840 Ty =
V->getType().getNonReferenceType();
4841 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4842 Ty = F->getType().getNonReferenceType();
4879 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4882 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4884 case AtomicExpr::AO__c11_atomic_init:
4885 case AtomicExpr::AO__opencl_atomic_init:
4886 llvm_unreachable(
"There is no ordering argument for an init");
4888 case AtomicExpr::AO__c11_atomic_load:
4889 case AtomicExpr::AO__opencl_atomic_load:
4890 case AtomicExpr::AO__hip_atomic_load:
4891 case AtomicExpr::AO__atomic_load_n:
4892 case AtomicExpr::AO__atomic_load:
4893 case AtomicExpr::AO__scoped_atomic_load_n:
4894 case AtomicExpr::AO__scoped_atomic_load:
4895 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4896 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4898 case AtomicExpr::AO__c11_atomic_store:
4899 case AtomicExpr::AO__opencl_atomic_store:
4900 case AtomicExpr::AO__hip_atomic_store:
4901 case AtomicExpr::AO__atomic_store:
4902 case AtomicExpr::AO__atomic_store_n:
4903 case AtomicExpr::AO__scoped_atomic_store:
4904 case AtomicExpr::AO__scoped_atomic_store_n:
4905 case AtomicExpr::AO__atomic_clear:
4906 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4907 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4908 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4938#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4939 case AtomicExpr::AO__hip_atomic_##hip: \
4940 OldName = "__hip_atomic_" #hip; \
4941 NewName = "__scoped_atomic_" #scoped; \
4954#undef HIP_ATOMIC_FIXABLE
4955 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4956 OldName =
"__hip_atomic_compare_exchange_weak";
4957 NewName =
"__scoped_atomic_compare_exchange";
4960 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4961 OldName =
"__hip_atomic_compare_exchange_strong";
4962 NewName =
"__scoped_atomic_compare_exchange";
4966 llvm_unreachable(
"unhandled HIP atomic op");
4969 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4970 << OldName << NewName;
4977 std::optional<llvm::APSInt> ScopeVal =
4982 StringRef ScopeName;
4983 switch (ScopeVal->getZExtValue()) {
4985 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4988 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4991 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4994 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4997 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
5000 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
5052 const unsigned NumForm = ClearByte + 1;
5053 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
5054 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
5062 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
5063 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
5064 "need to update code for modified forms");
5065 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
5066 AtomicExpr::AO__atomic_xor_fetch + 1 ==
5067 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
5068 "need to update code for modified C11 atomics");
5069 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
5070 Op <= AtomicExpr::AO__opencl_atomic_store;
5071 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
5072 Op <= AtomicExpr::AO__hip_atomic_store;
5073 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
5074 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
5075 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
5076 Op <= AtomicExpr::AO__c11_atomic_store) ||
5078 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
5079 Op == AtomicExpr::AO__atomic_store_n ||
5080 Op == AtomicExpr::AO__atomic_exchange_n ||
5081 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
5082 Op == AtomicExpr::AO__scoped_atomic_load_n ||
5083 Op == AtomicExpr::AO__scoped_atomic_store_n ||
5084 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
5085 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
5089 enum ArithOpExtraValueType {
5095 unsigned ArithAllows = AOEVT_None;
5098 case AtomicExpr::AO__c11_atomic_init:
5099 case AtomicExpr::AO__opencl_atomic_init:
5103 case AtomicExpr::AO__c11_atomic_load:
5104 case AtomicExpr::AO__opencl_atomic_load:
5105 case AtomicExpr::AO__hip_atomic_load:
5106 case AtomicExpr::AO__atomic_load_n:
5107 case AtomicExpr::AO__scoped_atomic_load_n:
5108 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5112 case AtomicExpr::AO__atomic_load:
5113 case AtomicExpr::AO__scoped_atomic_load:
5114 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5118 case AtomicExpr::AO__c11_atomic_store:
5119 case AtomicExpr::AO__opencl_atomic_store:
5120 case AtomicExpr::AO__hip_atomic_store:
5121 case AtomicExpr::AO__atomic_store:
5122 case AtomicExpr::AO__atomic_store_n:
5123 case AtomicExpr::AO__scoped_atomic_store:
5124 case AtomicExpr::AO__scoped_atomic_store_n:
5125 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5128 case AtomicExpr::AO__atomic_fetch_add:
5129 case AtomicExpr::AO__atomic_fetch_sub:
5130 case AtomicExpr::AO__atomic_add_fetch:
5131 case AtomicExpr::AO__atomic_sub_fetch:
5132 case AtomicExpr::AO__scoped_atomic_fetch_add:
5133 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5134 case AtomicExpr::AO__scoped_atomic_add_fetch:
5135 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5136 case AtomicExpr::AO__c11_atomic_fetch_add:
5137 case AtomicExpr::AO__c11_atomic_fetch_sub:
5138 case AtomicExpr::AO__opencl_atomic_fetch_add:
5139 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5140 case AtomicExpr::AO__hip_atomic_fetch_add:
5141 case AtomicExpr::AO__hip_atomic_fetch_sub:
5142 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5145 case AtomicExpr::AO__atomic_fetch_fminimum:
5146 case AtomicExpr::AO__atomic_fetch_fmaximum:
5147 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5148 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5149 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5150 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5151 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5152 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5153 ArithAllows = AOEVT_FP;
5156 case AtomicExpr::AO__atomic_fetch_max:
5157 case AtomicExpr::AO__atomic_fetch_min:
5158 case AtomicExpr::AO__atomic_max_fetch:
5159 case AtomicExpr::AO__atomic_min_fetch:
5160 case AtomicExpr::AO__scoped_atomic_fetch_max:
5161 case AtomicExpr::AO__scoped_atomic_fetch_min:
5162 case AtomicExpr::AO__scoped_atomic_max_fetch:
5163 case AtomicExpr::AO__scoped_atomic_min_fetch:
5164 case AtomicExpr::AO__c11_atomic_fetch_max:
5165 case AtomicExpr::AO__c11_atomic_fetch_min:
5166 case AtomicExpr::AO__opencl_atomic_fetch_max:
5167 case AtomicExpr::AO__opencl_atomic_fetch_min:
5168 case AtomicExpr::AO__hip_atomic_fetch_max:
5169 case AtomicExpr::AO__hip_atomic_fetch_min:
5170 ArithAllows = AOEVT_Int | AOEVT_FP;
5173 case AtomicExpr::AO__c11_atomic_fetch_and:
5174 case AtomicExpr::AO__c11_atomic_fetch_or:
5175 case AtomicExpr::AO__c11_atomic_fetch_xor:
5176 case AtomicExpr::AO__hip_atomic_fetch_and:
5177 case AtomicExpr::AO__hip_atomic_fetch_or:
5178 case AtomicExpr::AO__hip_atomic_fetch_xor:
5179 case AtomicExpr::AO__c11_atomic_fetch_nand:
5180 case AtomicExpr::AO__opencl_atomic_fetch_and:
5181 case AtomicExpr::AO__opencl_atomic_fetch_or:
5182 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5183 case AtomicExpr::AO__atomic_fetch_and:
5184 case AtomicExpr::AO__atomic_fetch_or:
5185 case AtomicExpr::AO__atomic_fetch_xor:
5186 case AtomicExpr::AO__atomic_fetch_nand:
5187 case AtomicExpr::AO__atomic_and_fetch:
5188 case AtomicExpr::AO__atomic_or_fetch:
5189 case AtomicExpr::AO__atomic_xor_fetch:
5190 case AtomicExpr::AO__atomic_nand_fetch:
5191 case AtomicExpr::AO__atomic_fetch_uinc:
5192 case AtomicExpr::AO__atomic_fetch_udec:
5193 case AtomicExpr::AO__scoped_atomic_fetch_and:
5194 case AtomicExpr::AO__scoped_atomic_fetch_or:
5195 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5196 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5197 case AtomicExpr::AO__scoped_atomic_and_fetch:
5198 case AtomicExpr::AO__scoped_atomic_or_fetch:
5199 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5200 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5201 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5202 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5206 case AtomicExpr::AO__c11_atomic_exchange:
5207 case AtomicExpr::AO__hip_atomic_exchange:
5208 case AtomicExpr::AO__opencl_atomic_exchange:
5209 case AtomicExpr::AO__atomic_exchange_n:
5210 case AtomicExpr::AO__scoped_atomic_exchange_n:
5211 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5215 case AtomicExpr::AO__atomic_exchange:
5216 case AtomicExpr::AO__scoped_atomic_exchange:
5217 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5221 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5222 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5223 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5224 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5225 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5226 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5230 case AtomicExpr::AO__atomic_compare_exchange:
5231 case AtomicExpr::AO__atomic_compare_exchange_n:
5232 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5233 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5234 ArithAllows = AOEVT_Pointer;
5238 case AtomicExpr::AO__atomic_test_and_set:
5239 Form = TestAndSetByte;
5242 case AtomicExpr::AO__atomic_clear:
5247 unsigned AdjustedNumArgs = NumArgs[Form];
5248 if ((IsOpenCL || IsHIP || IsScoped) &&
5249 Op != AtomicExpr::AO__opencl_atomic_init)
5252 if (Args.size() < AdjustedNumArgs) {
5253 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5254 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5257 }
else if (Args.size() > AdjustedNumArgs) {
5258 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5259 diag::err_typecheck_call_too_many_args)
5260 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5266 Expr *Ptr = Args[0];
5271 Ptr = ConvertedPtr.
get();
5274 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5275 << Ptr->getType() << 0 << Ptr->getSourceRange();
5284 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5285 << Ptr->getType() << Ptr->getSourceRange();
5290 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5292 << Ptr->getSourceRange();
5296 }
else if (Form != Load && Form != LoadCopy) {
5298 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5299 << Ptr->getType() << Ptr->getSourceRange();
5304 if (Form != TestAndSetByte && Form != ClearByte) {
5307 diag::err_incomplete_type))
5310 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5311 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5312 << Ptr->getType() << 1 << Ptr->getSourceRange();
5321 pointerType->getPointeeType().getCVRQualifiers());
5331 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5332 << 0 << Ptr->getType() << Ptr->getSourceRange();
5341 auto IsAllowedValueType = [&](
QualType ValType,
5342 unsigned AllowedType) ->
bool {
5343 bool IsX87LongDouble =
5345 &
Context.getTargetInfo().getLongDoubleFormat() ==
5346 &llvm::APFloat::x87DoubleExtended();
5350 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5352 return AllowedType & AOEVT_Pointer;
5356 if (IsX87LongDouble)
5360 if (!IsAllowedValueType(ValType, ArithAllows)) {
5362 ArithAllows == AOEVT_FP
5363 ? diag::err_atomic_op_needs_atomic_fp
5364 : (ArithAllows & AOEVT_FP
5365 ? (ArithAllows & AOEVT_Pointer
5366 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5367 : diag::err_atomic_op_needs_atomic_int_or_fp)
5368 : (ArithAllows & AOEVT_Pointer
5369 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5370 : diag::err_atomic_op_needs_atomic_int));
5372 << IsC11 << Ptr->getType() << Ptr->getSourceRange();
5377 diag::err_incomplete_type)) {
5388 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5389 << Ptr->getType() << Ptr->getSourceRange();
5404 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5405 << ValType << Ptr->getSourceRange();
5416 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5419 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5425 bool IsPassedByAddress =
false;
5426 if (!IsC11 && !IsHIP && !IsN) {
5427 ByValType = Ptr->getType();
5428 IsPassedByAddress =
true;
5433 APIOrderedArgs.push_back(Args[0]);
5437 APIOrderedArgs.push_back(Args[1]);
5443 APIOrderedArgs.push_back(Args[2]);
5444 APIOrderedArgs.push_back(Args[1]);
5447 APIOrderedArgs.push_back(Args[2]);
5448 APIOrderedArgs.push_back(Args[3]);
5449 APIOrderedArgs.push_back(Args[1]);
5452 APIOrderedArgs.push_back(Args[2]);
5453 APIOrderedArgs.push_back(Args[4]);
5454 APIOrderedArgs.push_back(Args[1]);
5455 APIOrderedArgs.push_back(Args[3]);
5458 APIOrderedArgs.push_back(Args[2]);
5459 APIOrderedArgs.push_back(Args[4]);
5460 APIOrderedArgs.push_back(Args[5]);
5461 APIOrderedArgs.push_back(Args[1]);
5462 APIOrderedArgs.push_back(Args[3]);
5464 case TestAndSetByte:
5466 APIOrderedArgs.push_back(Args[1]);
5470 APIOrderedArgs.append(Args.begin(), Args.end());
5477 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5479 if (i < NumVals[Form] + 1) {
5492 assert(Form != Load);
5494 Ty =
Context.getPointerDiffType();
5497 else if (Form ==
Copy || Form == Xchg) {
5498 if (IsPassedByAddress) {
5505 Expr *ValArg = APIOrderedArgs[i];
5512 AS = PtrTy->getPointeeType().getAddressSpace();
5521 if (IsPassedByAddress)
5541 APIOrderedArgs[i] = Arg.
get();
5546 SubExprs.push_back(Ptr);
5550 SubExprs.push_back(APIOrderedArgs[1]);
5553 case TestAndSetByte:
5555 SubExprs.push_back(APIOrderedArgs[1]);
5561 SubExprs.push_back(APIOrderedArgs[2]);
5562 SubExprs.push_back(APIOrderedArgs[1]);
5566 SubExprs.push_back(APIOrderedArgs[3]);
5567 SubExprs.push_back(APIOrderedArgs[1]);
5568 SubExprs.push_back(APIOrderedArgs[2]);
5571 SubExprs.push_back(APIOrderedArgs[3]);
5572 SubExprs.push_back(APIOrderedArgs[1]);
5573 SubExprs.push_back(APIOrderedArgs[4]);
5574 SubExprs.push_back(APIOrderedArgs[2]);
5577 SubExprs.push_back(APIOrderedArgs[4]);
5578 SubExprs.push_back(APIOrderedArgs[1]);
5579 SubExprs.push_back(APIOrderedArgs[5]);
5580 SubExprs.push_back(APIOrderedArgs[2]);
5581 SubExprs.push_back(APIOrderedArgs[3]);
5586 if (SubExprs.size() >= 2 && Form !=
Init) {
5587 std::optional<llvm::APSInt>
Success =
5588 SubExprs[1]->getIntegerConstantExpr(
Context);
5590 Diag(SubExprs[1]->getBeginLoc(),
5591 diag::warn_atomic_op_has_invalid_memory_order)
5592 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5593 << SubExprs[1]->getSourceRange();
5595 if (SubExprs.size() >= 5) {
5596 if (std::optional<llvm::APSInt>
Failure =
5597 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5598 if (!llvm::is_contained(
5599 {llvm::AtomicOrderingCABI::relaxed,
5600 llvm::AtomicOrderingCABI::consume,
5601 llvm::AtomicOrderingCABI::acquire,
5602 llvm::AtomicOrderingCABI::seq_cst},
5603 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5604 Diag(SubExprs[3]->getBeginLoc(),
5605 diag::warn_atomic_op_has_invalid_memory_order)
5606 << 2 << SubExprs[3]->getSourceRange();
5613 auto *
Scope = Args[Args.size() - 1];
5614 if (std::optional<llvm::APSInt>
Result =
5616 if (!ScopeModel->isValid(
Result->getZExtValue()))
5617 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5618 <<
Scope->getSourceRange();
5620 SubExprs.push_back(
Scope);
5629 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5630 Op == AtomicExpr::AO__c11_atomic_store ||
5631 Op == AtomicExpr::AO__opencl_atomic_load ||
5632 Op == AtomicExpr::AO__hip_atomic_load ||
5633 Op == AtomicExpr::AO__opencl_atomic_store ||
5634 Op == AtomicExpr::AO__hip_atomic_store) &&
5635 Context.AtomicUsesUnsupportedLibcall(AE))
5637 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5638 Op == AtomicExpr::AO__opencl_atomic_load ||
5639 Op == AtomicExpr::AO__hip_atomic_load)
5644 Diag(Ptr->getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5660 assert(Fn &&
"builtin call without direct callee!");
5676 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5683 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5685 <<
Callee->getSourceRange();
5694 Expr *FirstArg = TheCall->
getArg(0);
5698 FirstArg = FirstArgResult.
get();
5699 TheCall->
setArg(0, FirstArg);
5711 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5718 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5748 QualType ResultType = ValType;
5753#define BUILTIN_ROW(x) \
5754 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5755 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5757 static const unsigned BuiltinIndices[][5] = {
5782 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5783 case 1: SizeIndex = 0;
break;
5784 case 2: SizeIndex = 1;
break;
5785 case 4: SizeIndex = 2;
break;
5786 case 8: SizeIndex = 3;
break;
5787 case 16: SizeIndex = 4;
break;
5799 unsigned BuiltinIndex, NumFixed = 1;
5800 bool WarnAboutSemanticsChange =
false;
5801 switch (BuiltinID) {
5802 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5803 case Builtin::BI__sync_fetch_and_add:
5804 case Builtin::BI__sync_fetch_and_add_1:
5805 case Builtin::BI__sync_fetch_and_add_2:
5806 case Builtin::BI__sync_fetch_and_add_4:
5807 case Builtin::BI__sync_fetch_and_add_8:
5808 case Builtin::BI__sync_fetch_and_add_16:
5812 case Builtin::BI__sync_fetch_and_sub:
5813 case Builtin::BI__sync_fetch_and_sub_1:
5814 case Builtin::BI__sync_fetch_and_sub_2:
5815 case Builtin::BI__sync_fetch_and_sub_4:
5816 case Builtin::BI__sync_fetch_and_sub_8:
5817 case Builtin::BI__sync_fetch_and_sub_16:
5821 case Builtin::BI__sync_fetch_and_or:
5822 case Builtin::BI__sync_fetch_and_or_1:
5823 case Builtin::BI__sync_fetch_and_or_2:
5824 case Builtin::BI__sync_fetch_and_or_4:
5825 case Builtin::BI__sync_fetch_and_or_8:
5826 case Builtin::BI__sync_fetch_and_or_16:
5830 case Builtin::BI__sync_fetch_and_and:
5831 case Builtin::BI__sync_fetch_and_and_1:
5832 case Builtin::BI__sync_fetch_and_and_2:
5833 case Builtin::BI__sync_fetch_and_and_4:
5834 case Builtin::BI__sync_fetch_and_and_8:
5835 case Builtin::BI__sync_fetch_and_and_16:
5839 case Builtin::BI__sync_fetch_and_xor:
5840 case Builtin::BI__sync_fetch_and_xor_1:
5841 case Builtin::BI__sync_fetch_and_xor_2:
5842 case Builtin::BI__sync_fetch_and_xor_4:
5843 case Builtin::BI__sync_fetch_and_xor_8:
5844 case Builtin::BI__sync_fetch_and_xor_16:
5848 case Builtin::BI__sync_fetch_and_nand:
5849 case Builtin::BI__sync_fetch_and_nand_1:
5850 case Builtin::BI__sync_fetch_and_nand_2:
5851 case Builtin::BI__sync_fetch_and_nand_4:
5852 case Builtin::BI__sync_fetch_and_nand_8:
5853 case Builtin::BI__sync_fetch_and_nand_16:
5855 WarnAboutSemanticsChange =
true;
5858 case Builtin::BI__sync_add_and_fetch:
5859 case Builtin::BI__sync_add_and_fetch_1:
5860 case Builtin::BI__sync_add_and_fetch_2:
5861 case Builtin::BI__sync_add_and_fetch_4:
5862 case Builtin::BI__sync_add_and_fetch_8:
5863 case Builtin::BI__sync_add_and_fetch_16:
5867 case Builtin::BI__sync_sub_and_fetch:
5868 case Builtin::BI__sync_sub_and_fetch_1:
5869 case Builtin::BI__sync_sub_and_fetch_2:
5870 case Builtin::BI__sync_sub_and_fetch_4:
5871 case Builtin::BI__sync_sub_and_fetch_8:
5872 case Builtin::BI__sync_sub_and_fetch_16:
5876 case Builtin::BI__sync_and_and_fetch:
5877 case Builtin::BI__sync_and_and_fetch_1:
5878 case Builtin::BI__sync_and_and_fetch_2:
5879 case Builtin::BI__sync_and_and_fetch_4:
5880 case Builtin::BI__sync_and_and_fetch_8:
5881 case Builtin::BI__sync_and_and_fetch_16:
5885 case Builtin::BI__sync_or_and_fetch:
5886 case Builtin::BI__sync_or_and_fetch_1:
5887 case Builtin::BI__sync_or_and_fetch_2:
5888 case Builtin::BI__sync_or_and_fetch_4:
5889 case Builtin::BI__sync_or_and_fetch_8:
5890 case Builtin::BI__sync_or_and_fetch_16:
5894 case Builtin::BI__sync_xor_and_fetch:
5895 case Builtin::BI__sync_xor_and_fetch_1:
5896 case Builtin::BI__sync_xor_and_fetch_2:
5897 case Builtin::BI__sync_xor_and_fetch_4:
5898 case Builtin::BI__sync_xor_and_fetch_8:
5899 case Builtin::BI__sync_xor_and_fetch_16:
5903 case Builtin::BI__sync_nand_and_fetch:
5904 case Builtin::BI__sync_nand_and_fetch_1:
5905 case Builtin::BI__sync_nand_and_fetch_2:
5906 case Builtin::BI__sync_nand_and_fetch_4:
5907 case Builtin::BI__sync_nand_and_fetch_8:
5908 case Builtin::BI__sync_nand_and_fetch_16:
5910 WarnAboutSemanticsChange =
true;
5913 case Builtin::BI__sync_val_compare_and_swap:
5914 case Builtin::BI__sync_val_compare_and_swap_1:
5915 case Builtin::BI__sync_val_compare_and_swap_2:
5916 case Builtin::BI__sync_val_compare_and_swap_4:
5917 case Builtin::BI__sync_val_compare_and_swap_8:
5918 case Builtin::BI__sync_val_compare_and_swap_16:
5923 case Builtin::BI__sync_bool_compare_and_swap:
5924 case Builtin::BI__sync_bool_compare_and_swap_1:
5925 case Builtin::BI__sync_bool_compare_and_swap_2:
5926 case Builtin::BI__sync_bool_compare_and_swap_4:
5927 case Builtin::BI__sync_bool_compare_and_swap_8:
5928 case Builtin::BI__sync_bool_compare_and_swap_16:
5934 case Builtin::BI__sync_lock_test_and_set:
5935 case Builtin::BI__sync_lock_test_and_set_1:
5936 case Builtin::BI__sync_lock_test_and_set_2:
5937 case Builtin::BI__sync_lock_test_and_set_4:
5938 case Builtin::BI__sync_lock_test_and_set_8:
5939 case Builtin::BI__sync_lock_test_and_set_16:
5943 case Builtin::BI__sync_lock_release:
5944 case Builtin::BI__sync_lock_release_1:
5945 case Builtin::BI__sync_lock_release_2:
5946 case Builtin::BI__sync_lock_release_4:
5947 case Builtin::BI__sync_lock_release_8:
5948 case Builtin::BI__sync_lock_release_16:
5954 case Builtin::BI__sync_swap:
5955 case Builtin::BI__sync_swap_1:
5956 case Builtin::BI__sync_swap_2:
5957 case Builtin::BI__sync_swap_4:
5958 case Builtin::BI__sync_swap_8:
5959 case Builtin::BI__sync_swap_16:
5967 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5968 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5969 <<
Callee->getSourceRange();
5973 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5974 <<
Callee->getSourceRange();
5976 if (WarnAboutSemanticsChange) {
5977 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5978 <<
Callee->getSourceRange();
5983 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5984 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5985 FunctionDecl *NewBuiltinDecl;
5986 if (NewBuiltinID == BuiltinID)
5987 NewBuiltinDecl = FDecl;
5990 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5993 assert(Res.getFoundDecl());
5994 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5995 if (!NewBuiltinDecl)
6002 for (
unsigned i = 0; i != NumFixed; ++i) {
6031 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
6033 CK_BuiltinFnToFnPtr);
6044 const auto *BitIntValType = ValType->
getAs<BitIntType>();
6045 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
6046 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
6050 return TheCallResult;
6054 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
6059 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
6060 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
6061 "Unexpected nontemporal load/store builtin!");
6062 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
6063 unsigned numArgs = isStore ? 2 : 1;
6073 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
6079 PointerArg = PointerArgResult.
get();
6080 TheCall->
setArg(numArgs - 1, PointerArg);
6084 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
6097 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
6104 return TheCallResult;
6116 return TheCallResult;
6123 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6125 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6126 Literal = ObjcLiteral->getString();
6130 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6137 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6138 InitializedEntity Entity =
6148 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6149 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6150 TT.getArch() == llvm::Triple::aarch64_32);
6151 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6152 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6153 if (IsX64 || IsAArch64) {
6160 return S.
Diag(Fn->getBeginLoc(),
6161 diag::err_ms_va_start_used_in_sysv_function);
6168 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6169 return S.
Diag(Fn->getBeginLoc(),
6170 diag::err_va_start_used_in_wrong_abi_function)
6171 << !IsWindowsOrUEFI;
6177 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6185 bool IsVariadic =
false;
6188 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6189 IsVariadic =
Block->isVariadic();
6190 Params =
Block->parameters();
6191 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6194 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6195 IsVariadic = MD->isVariadic();
6197 Params = MD->parameters();
6200 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6204 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6209 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6214 *LastParam = Params.empty() ?
nullptr : Params.back();
6219bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6224 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6248 ParmVarDecl *LastParam;
6259 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6261 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6266 if (std::optional<llvm::APSInt> Val =
6268 Val &&
LangOpts.C23 && *Val == 0 &&
6269 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6270 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6277 SourceLocation ParamLoc;
6278 bool IsCRegister =
false;
6279 bool SecondArgIsLastNonVariadicArgument =
false;
6280 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6281 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6282 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6285 ParamLoc = PV->getLocation();
6291 if (!SecondArgIsLastNonVariadicArgument)
6293 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6294 else if (IsCRegister ||
Type->isReferenceType() ||
6295 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6298 if (!Context.isPromotableIntegerType(Type))
6300 const auto *ED = Type->getAsEnumDecl();
6303 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6305 unsigned Reason = 0;
6306 if (
Type->isReferenceType()) Reason = 1;
6307 else if (IsCRegister) Reason = 2;
6308 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6309 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6316 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6336 if (
Call->getNumArgs() < 3)
6338 diag::err_typecheck_call_too_few_args_at_least)
6339 << 0 << 3 <<
Call->getNumArgs()
6355 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6358 const QualType &ConstCharPtrTy =
6360 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6362 << Arg1->
getType() << ConstCharPtrTy << 1
6365 << 2 << Arg1->
getType() << ConstCharPtrTy;
6367 const QualType SizeTy =
Context.getSizeType();
6372 << Arg2->
getType() << SizeTy << 1
6375 << 3 << Arg2->
getType() << SizeTy;
6380bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6384 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6412 diag::err_typecheck_call_invalid_ordered_compare)
6420bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6421 unsigned BuiltinID) {
6426 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6427 BuiltinID == Builtin::BI__builtin_isinf ||
6428 BuiltinID == Builtin::BI__builtin_isinf_sign))
6432 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6433 BuiltinID == Builtin::BI__builtin_isunordered))
6437 bool IsFPClass = NumArgs == 2;
6440 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6444 for (
unsigned i = 0; i < FPArgNo; ++i) {
6445 Expr *Arg = TheCall->
getArg(i);
6458 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6467 OrigArg = Res.
get();
6469 TheCall->
setArg(FPArgNo, OrigArg);
6471 QualType VectorResultTy;
6472 QualType ElementTy = OrigArg->
getType();
6477 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6483 diag::err_typecheck_call_invalid_unary_fp)
6496 TheCall->
setArg(NumArgs - 1, MaskRes.
get());
6502 if (!VectorResultTy.
isNull())
6503 ResultTy = VectorResultTy;
6512bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6517 for (
unsigned I = 0; I != 2; ++I) {
6518 Expr *Arg = TheCall->
getArg(I);
6528 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6543 Expr *Real = TheCall->
getArg(0);
6544 Expr *Imag = TheCall->
getArg(1);
6547 diag::err_typecheck_call_different_arg_types)
6562 diag::err_typecheck_call_too_few_args_at_least)
6563 << 0 << 2 << NumArgs
6570 unsigned NumElements = 0;
6585 unsigned NumResElements = NumArgs - 2;
6594 diag::err_vec_builtin_incompatible_vector)
6599 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6601 diag::err_vec_builtin_incompatible_vector)
6606 }
else if (NumElements != NumResElements) {
6609 ?
Context.getExtVectorType(EltType, NumResElements)
6610 :
Context.getVectorType(EltType, NumResElements,
6615 for (
unsigned I = 2; I != NumArgs; ++I) {
6623 diag::err_shufflevector_nonconstant_argument)
6629 else if (
Result->getActiveBits() > 64 ||
6630 Result->getZExtValue() >= NumElements * 2)
6632 diag::err_shufflevector_argument_too_large)
6657 diag::err_convertvector_non_vector)
6660 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6662 <<
"__builtin_convertvector");
6667 if (SrcElts != DstElts)
6669 diag::err_convertvector_incompatible_vector)
6677bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6682 diag::err_typecheck_call_too_many_args_at_most)
6683 << 0 << 3 << NumArgs << 0
6688 for (
unsigned i = 1; i != NumArgs; ++i)
6695bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6696 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6697 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6707 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6717bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6718 Expr *Arg = TheCall->
getArg(0);
6729bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6731 Expr *Arg = TheCall->
getArg(1);
6735 if (
const auto *UE =
6737 if (UE->getKind() == UETT_AlignOf ||
6738 UE->getKind() == UETT_PreferredAlignOf)
6744 if (!
Result.isPowerOf2())
6745 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6752 if (
Result > std::numeric_limits<int32_t>::max())
6760bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6765 Expr *FirstArg = TheCall->
getArg(0);
6771 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6775 TheCall->
setArg(0, FirstArgResult.
get());
6779 Expr *SecondArg = TheCall->
getArg(1);
6787 if (!
Result.isPowerOf2())
6788 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6800 Expr *ThirdArg = TheCall->
getArg(2);
6803 TheCall->
setArg(2, ThirdArg);
6809bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6810 unsigned BuiltinID =
6812 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6815 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6816 if (NumArgs < NumRequiredArgs) {
6817 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6818 << 0 << NumRequiredArgs << NumArgs
6821 if (NumArgs >= NumRequiredArgs + 0x100) {
6823 diag::err_typecheck_call_too_many_args_at_most)
6824 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6835 if (Arg.isInvalid())
6837 TheCall->
setArg(i, Arg.get());
6842 unsigned FormatIdx = i;
6852 unsigned FirstDataArg = i;
6853 while (i < NumArgs) {
6871 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6873 bool Success = CheckFormatArguments(
6876 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6900 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6909 int High,
bool RangeIsError) {
6923 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6931 PDiag(diag::warn_argument_invalid_range)
6974 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6979 if (
Value.isNegative())
6990 if ((
Value & 0xFF) != 0)
7015 Result.setIsUnsigned(
true);
7020 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
7040 Result.setIsUnsigned(
true);
7048 diag::err_argument_not_shifted_byte_or_xxff)
7052bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
7053 if (!Context.getTargetInfo().hasSjLjLowering())
7054 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
7065 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
7071bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
7072 if (!Context.getTargetInfo().hasSjLjLowering())
7073 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
7078bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
7093 diag::err_builtin_counted_by_ref_invalid_arg)
7098 diag::err_builtin_counted_by_ref_has_side_effects)
7101 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
7103 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
7108 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
7115 QualType MemberTy = ME->getMemberDecl()->getType();
7118 diag::err_builtin_counted_by_ref_invalid_arg)
7122 diag::err_builtin_counted_by_ref_invalid_arg)
7132bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7134 const CallExpr *CE =
7143 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7148 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7153 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7157 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7161 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7171class UncoveredArgHandler {
7172 enum {
Unknown = -1, AllCovered = -2 };
7174 signed FirstUncoveredArg =
Unknown;
7175 SmallVector<const Expr *, 4> DiagnosticExprs;
7178 UncoveredArgHandler() =
default;
7180 bool hasUncoveredArg()
const {
7181 return (FirstUncoveredArg >= 0);
7184 unsigned getUncoveredArg()
const {
7185 assert(hasUncoveredArg() &&
"no uncovered argument");
7186 return FirstUncoveredArg;
7189 void setAllCovered() {
7192 DiagnosticExprs.clear();
7193 FirstUncoveredArg = AllCovered;
7196 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7197 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7200 if (FirstUncoveredArg == AllCovered)
7205 if (NewFirstUncoveredArg == FirstUncoveredArg)
7206 DiagnosticExprs.push_back(StrExpr);
7207 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7208 DiagnosticExprs.clear();
7209 DiagnosticExprs.push_back(StrExpr);
7210 FirstUncoveredArg = NewFirstUncoveredArg;
7214 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7217enum StringLiteralCheckType {
7219 SLCT_UncheckedLiteral,
7227 bool AddendIsRight) {
7228 unsigned BitWidth = Offset.getBitWidth();
7229 unsigned AddendBitWidth = Addend.getBitWidth();
7231 if (Addend.isUnsigned()) {
7232 Addend = Addend.zext(++AddendBitWidth);
7233 Addend.setIsSigned(
true);
7236 if (AddendBitWidth > BitWidth) {
7237 Offset = Offset.sext(AddendBitWidth);
7238 BitWidth = AddendBitWidth;
7239 }
else if (BitWidth > AddendBitWidth) {
7240 Addend = Addend.sext(BitWidth);
7244 llvm::APSInt ResOffset = Offset;
7245 if (BinOpKind == BO_Add)
7246 ResOffset = Offset.sadd_ov(Addend, Ov);
7248 assert(AddendIsRight && BinOpKind == BO_Sub &&
7249 "operator must be add or sub with addend on the right");
7250 ResOffset = Offset.ssub_ov(Addend, Ov);
7256 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7257 "index (intermediate) result too big");
7258 Offset = Offset.sext(2 * BitWidth);
7259 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7263 Offset = std::move(ResOffset);
7271class FormatStringLiteral {
7272 const StringLiteral *FExpr;
7276 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7277 : FExpr(fexpr), Offset(Offset) {}
7279 const StringLiteral *getFormatString()
const {
return FExpr; }
7281 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7283 unsigned getByteLength()
const {
7284 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7287 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7294 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7295 bool isWide()
const {
return FExpr->
isWide(); }
7296 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7297 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7298 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7299 bool isPascal()
const {
return FExpr->
isPascal(); }
7301 SourceLocation getLocationOfByte(
7302 unsigned ByteNo,
const SourceManager &SM,
const LangOptions &Features,
7303 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7304 unsigned *StartTokenByteOffset =
nullptr)
const {
7306 StartToken, StartTokenByteOffset);
7309 SourceLocation getBeginLoc() const LLVM_READONLY {
7313 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7319 Sema &S,
const FormatStringLiteral *FExpr,
7324 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7325 bool IgnoreStringsWithoutSpecifiers);
7334static StringLiteralCheckType
7340 llvm::SmallBitVector &CheckedVarArgs,
7341 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7342 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7343 bool IgnoreStringsWithoutSpecifiers =
false) {
7345 return SLCT_NotALiteral;
7347 assert(Offset.isSigned() &&
"invalid offset");
7350 return SLCT_NotALiteral;
7359 return SLCT_UncheckedLiteral;
7362 case Stmt::InitListExprClass:
7366 format_idx, firstDataArg,
Type, CallType,
7367 false, CheckedVarArgs,
7368 UncoveredArg, Offset, CallerFormatParamIdx,
7369 IgnoreStringsWithoutSpecifiers);
7371 return SLCT_NotALiteral;
7372 case Stmt::BinaryConditionalOperatorClass:
7373 case Stmt::ConditionalOperatorClass: {
7382 bool CheckLeft =
true, CheckRight =
true;
7385 if (
C->getCond()->EvaluateAsBooleanCondition(
7397 StringLiteralCheckType Left;
7399 Left = SLCT_UncheckedLiteral;
7402 Args, APK, format_idx, firstDataArg,
Type,
7403 CallType, InFunctionCall, CheckedVarArgs,
7404 UncoveredArg, Offset, CallerFormatParamIdx,
7405 IgnoreStringsWithoutSpecifiers);
7406 if (Left == SLCT_NotALiteral || !CheckRight) {
7412 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7413 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7414 UncoveredArg, Offset, CallerFormatParamIdx,
7415 IgnoreStringsWithoutSpecifiers);
7417 return (CheckLeft && Left < Right) ? Left : Right;
7420 case Stmt::ImplicitCastExprClass:
7424 case Stmt::OpaqueValueExprClass:
7429 return SLCT_NotALiteral;
7431 case Stmt::PredefinedExprClass:
7435 return SLCT_UncheckedLiteral;
7437 case Stmt::DeclRefExprClass: {
7443 bool isConstant =
false;
7447 isConstant = AT->getElementType().isConstant(S.
Context);
7449 isConstant =
T.isConstant(S.
Context) &&
7450 PT->getPointeeType().isConstant(S.
Context);
7451 }
else if (
T->isObjCObjectPointerType()) {
7454 isConstant =
T.isConstant(S.
Context);
7458 if (
const Expr *
Init = VD->getAnyInitializer()) {
7461 if (InitList->isStringLiteralInit())
7462 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7465 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7466 firstDataArg,
Type, CallType,
false,
7467 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7518 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7519 if (CallerFormatParamIdx)
7520 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7521 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7522 for (
const auto *PVFormatMatches :
7523 D->specific_attrs<FormatMatchesAttr>()) {
7528 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7532 S.
Diag(Args[format_idx]->getBeginLoc(),
7533 diag::warn_format_string_type_incompatible)
7534 << PVFormatMatches->getType()->getName()
7536 if (!InFunctionCall) {
7537 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7538 diag::note_format_string_defined);
7540 return SLCT_UncheckedLiteral;
7543 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7544 Args, APK, format_idx, firstDataArg,
Type, CallType,
7545 false, CheckedVarArgs, UncoveredArg,
7546 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7550 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7553 PVFormat->getFirstArg(), &CallerFSI))
7555 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7559 S.
Diag(Args[format_idx]->getBeginLoc(),
7560 diag::warn_format_string_type_incompatible)
7561 << PVFormat->getType()->getName()
7563 if (!InFunctionCall) {
7566 return SLCT_UncheckedLiteral;
7579 return SLCT_UncheckedLiteral;
7587 return SLCT_NotALiteral;
7590 case Stmt::CallExprClass:
7591 case Stmt::CXXMemberCallExprClass: {
7595 StringLiteralCheckType CommonResult;
7596 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7597 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7599 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7600 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7601 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7608 return CommonResult;
7610 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7612 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7613 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7616 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7617 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7618 UncoveredArg, Offset, CallerFormatParamIdx,
7619 IgnoreStringsWithoutSpecifiers);
7625 format_idx, firstDataArg,
Type, CallType,
7626 false, CheckedVarArgs,
7627 UncoveredArg, Offset, CallerFormatParamIdx,
7628 IgnoreStringsWithoutSpecifiers);
7629 return SLCT_NotALiteral;
7631 case Stmt::ObjCMessageExprClass: {
7633 if (
const auto *MD = ME->getMethodDecl()) {
7634 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7643 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7645 MD->getSelector().isKeywordSelector(
7646 {
"localizedStringForKey",
"value",
"table"})) {
7647 IgnoreStringsWithoutSpecifiers =
true;
7650 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7652 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7653 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7654 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7658 return SLCT_NotALiteral;
7660 case Stmt::ObjCStringLiteralClass:
7661 case Stmt::StringLiteralClass: {
7670 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7673 return SLCT_NotALiteral;
7675 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7677 format_idx, firstDataArg,
Type, InFunctionCall,
7678 CallType, CheckedVarArgs, UncoveredArg,
7679 IgnoreStringsWithoutSpecifiers);
7680 return SLCT_CheckedLiteral;
7683 return SLCT_NotALiteral;
7685 case Stmt::BinaryOperatorClass: {
7699 if (LIsInt != RIsInt) {
7703 if (BinOpKind == BO_Add) {
7716 return SLCT_NotALiteral;
7718 case Stmt::UnaryOperatorClass: {
7720 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7721 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7723 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7733 return SLCT_NotALiteral;
7737 return SLCT_NotALiteral;
7748 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7749 if (isa_and_nonnull<StringLiteral>(LVE))
7770 return "freebsd_kprintf";
7779 return llvm::StringSwitch<FormatStringType>(Flavor)
7781 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7786 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7802bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7806 llvm::SmallBitVector &CheckedVarArgs) {
7807 FormatStringInfo FSI;
7811 return CheckFormatArguments(
7812 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7817bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7821 llvm::SmallBitVector &CheckedVarArgs) {
7822 FormatStringInfo FSI;
7826 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7827 Format->getFormatString(), FSI.FormatIdx,
7829 CallType, Loc, Range, CheckedVarArgs);
7837 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7850 unsigned CallerArgumentIndexOffset =
7853 unsigned FirstArgumentIndex = -1;
7863 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7864 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7868 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7869 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7871 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7874 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7875 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7878 FirstArgumentIndex =
7879 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7885 ? (NumCallerParams + CallerArgumentIndexOffset)
7890 if (!ReferenceFormatString)
7896 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7898 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7900 std::string
Attr, Fixit;
7901 llvm::raw_string_ostream AttrOS(
Attr);
7903 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7904 << FirstArgumentIndex <<
")";
7906 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7908 AttrOS.write_escaped(ReferenceFormatString->
getString());
7912 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7923 llvm::raw_string_ostream IS(Fixit);
7931 if (LO.C23 || LO.CPlusPlus11)
7932 IS <<
"[[gnu::" <<
Attr <<
"]]";
7933 else if (LO.ObjC || LO.GNUMode)
7934 IS <<
"__attribute__((" <<
Attr <<
"))";
7948 Caller->
addAttr(FormatAttr::CreateImplicit(
7950 FormatStringIndex, FirstArgumentIndex));
7952 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7954 FormatStringIndex, ReferenceFormatString));
7958 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7970 unsigned format_idx,
unsigned firstDataArg,
7974 llvm::SmallBitVector &CheckedVarArgs) {
7976 if (format_idx >= Args.size()) {
7977 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7981 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7995 UncoveredArgHandler UncoveredArg;
7996 std::optional<unsigned> CallerParamIdx;
7998 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7999 firstDataArg,
Type, CallType,
8000 true, CheckedVarArgs, UncoveredArg,
8001 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
8004 if (UncoveredArg.hasUncoveredArg()) {
8005 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
8006 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
8007 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
8010 if (CT != SLCT_NotALiteral)
8012 return CT == SLCT_CheckedLiteral;
8018 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
8024 this, Args, APK, ReferenceFormatString, format_idx,
8025 firstDataArg,
Type, *CallerParamIdx, Loc))
8035 if (Args.size() == firstDataArg) {
8036 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
8044 Diag(FormatLoc, diag::note_format_security_fixit)
8048 Diag(FormatLoc, diag::note_format_security_fixit)
8053 Diag(FormatLoc, diag::warn_format_nonliteral)
8064 const FormatStringLiteral *FExpr;
8065 const Expr *OrigFormatExpr;
8067 const unsigned FirstDataArg;
8068 const unsigned NumDataArgs;
8071 ArrayRef<const Expr *> Args;
8073 llvm::SmallBitVector CoveredArgs;
8074 bool usesPositionalArgs =
false;
8075 bool atFirstArg =
true;
8076 bool inFunctionCall;
8078 llvm::SmallBitVector &CheckedVarArgs;
8079 UncoveredArgHandler &UncoveredArg;
8082 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
8084 unsigned firstDataArg,
unsigned numDataArgs,
8086 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8088 llvm::SmallBitVector &CheckedVarArgs,
8089 UncoveredArgHandler &UncoveredArg)
8090 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
8091 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
8092 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
8093 inFunctionCall(inFunctionCall), CallType(callType),
8094 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
8095 CoveredArgs.resize(numDataArgs);
8096 CoveredArgs.reset();
8099 bool HasFormatArguments()
const {
8104 void DoneProcessing();
8106 void HandleIncompleteSpecifier(
const char *startSpecifier,
8107 unsigned specifierLen)
override;
8109 void HandleInvalidLengthModifier(
8110 const analyze_format_string::FormatSpecifier &FS,
8111 const analyze_format_string::ConversionSpecifier &CS,
8112 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
8114 void HandleNonStandardLengthModifier(
8115 const analyze_format_string::FormatSpecifier &FS,
8116 const char *startSpecifier,
unsigned specifierLen);
8118 void HandleNonStandardConversionSpecifier(
8119 const analyze_format_string::ConversionSpecifier &CS,
8120 const char *startSpecifier,
unsigned specifierLen);
8122 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
8124 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
8127 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
8129 void HandleNullChar(
const char *nullCharacter)
override;
8131 template <
typename Range>
8133 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8134 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8135 bool IsStringLocation, Range StringRange,
8136 ArrayRef<FixItHint> Fixit = {});
8139 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8140 const char *startSpec,
8141 unsigned specifierLen,
8142 const char *csStart,
unsigned csLen);
8144 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8145 const char *startSpec,
8146 unsigned specifierLen);
8148 SourceRange getFormatStringRange();
8149 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8150 unsigned specifierLen);
8151 SourceLocation getLocationOfByte(
const char *x);
8153 const Expr *getDataArg(
unsigned i)
const;
8155 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8156 const analyze_format_string::ConversionSpecifier &CS,
8157 const char *startSpecifier,
unsigned specifierLen,
8160 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8161 const Expr *E,
const char *startSpecifier,
8162 unsigned specifierLen);
8164 template <
typename Range>
8165 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8166 bool IsStringLocation, Range StringRange,
8167 ArrayRef<FixItHint> Fixit = {});
8172SourceRange CheckFormatHandler::getFormatStringRange() {
8177CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8178 unsigned specifierLen) {
8180 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8188SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8193void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8194 unsigned specifierLen) {
8195 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8196 getLocationOfByte(startSpecifier),
8198 getSpecifierRange(startSpecifier, specifierLen));
8201bool CheckFormatHandler::CheckUnsupportedType(
8203 const char *StartSpecifier,
unsigned SpecifierLen) {
8207 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8210 getSpecifierRange(StartSpecifier, SpecifierLen));
8214void CheckFormatHandler::HandleInvalidLengthModifier(
8217 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8229 getSpecifierRange(startSpecifier, specifierLen));
8231 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8232 << FixedLM->toString()
8237 if (DiagID == diag::warn_format_nonsensical_length)
8243 getSpecifierRange(startSpecifier, specifierLen), Hint);
8247void CheckFormatHandler::HandleNonStandardLengthModifier(
8249 const char *startSpecifier,
unsigned specifierLen) {
8258 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8262 getSpecifierRange(startSpecifier, specifierLen));
8264 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8265 << FixedLM->toString()
8269 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8273 getSpecifierRange(startSpecifier, specifierLen));
8277void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8279 const char *startSpecifier,
unsigned specifierLen) {
8285 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8289 getSpecifierRange(startSpecifier, specifierLen));
8292 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8293 << FixedCS->toString()
8296 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8300 getSpecifierRange(startSpecifier, specifierLen));
8304void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8306 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8307 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8308 getLocationOfByte(startPos),
8310 getSpecifierRange(startPos, posLen));
8313void CheckFormatHandler::HandleInvalidPosition(
8314 const char *startSpecifier,
unsigned specifierLen,
8317 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8318 EmitFormatDiagnostic(
8319 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8320 getLocationOfByte(startSpecifier),
true,
8321 getSpecifierRange(startSpecifier, specifierLen));
8324void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8328 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8329 getLocationOfByte(startPos),
8331 getSpecifierRange(startPos, posLen));
8334void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8337 EmitFormatDiagnostic(
8338 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8339 getLocationOfByte(nullCharacter),
true,
8340 getFormatStringRange());
8346const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8347 return Args[FirstDataArg + i];
8350void CheckFormatHandler::DoneProcessing() {
8353 if (HasFormatArguments()) {
8356 signed notCoveredArg = CoveredArgs.find_first();
8357 if (notCoveredArg >= 0) {
8358 assert((
unsigned)notCoveredArg < NumDataArgs);
8359 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8361 UncoveredArg.setAllCovered();
8366void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8367 const Expr *ArgExpr) {
8368 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8379 for (
auto E : DiagnosticExprs)
8382 CheckFormatHandler::EmitFormatDiagnostic(
8383 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8387bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8389 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8390 bool keepGoing =
true;
8391 if (argIndex < NumDataArgs) {
8394 CoveredArgs.set(argIndex);
8409 std::string CodePointStr;
8410 if (!llvm::sys::locale::isPrint(*csStart)) {
8411 llvm::UTF32 CodePoint;
8412 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8413 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8414 llvm::ConversionResult
Result =
8415 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8417 if (
Result != llvm::conversionOK) {
8418 unsigned char FirstChar = *csStart;
8419 CodePoint = (llvm::UTF32)FirstChar;
8422 llvm::raw_string_ostream
OS(CodePointStr);
8423 if (CodePoint < 256)
8424 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8425 else if (CodePoint <= 0xFFFF)
8426 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8428 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8432 EmitFormatDiagnostic(
8433 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8434 true, getSpecifierRange(startSpec, specifierLen));
8439void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8440 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8441 EmitFormatDiagnostic(
8442 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8443 true, getSpecifierRange(startSpec, specifierLen));
8446bool CheckFormatHandler::CheckNumArgs(
8449 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8451 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8454 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8455 << (argIndex + 1) << NumDataArgs)
8456 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8457 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8459 getSpecifierRange(startSpecifier, specifierLen));
8463 UncoveredArg.setAllCovered();
8469template <
typename Range>
8472 bool IsStringLocation,
8475 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8476 IsStringLocation, StringRange, FixIt);
8506template <
typename Range>
8507void CheckFormatHandler::EmitFormatDiagnostic(
8508 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8511 if (InFunctionCall) {
8516 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8520 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8521 diag::note_format_string_defined);
8523 Note << StringRange;
8532class CheckPrintfHandler :
public CheckFormatHandler {
8534 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8536 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8538 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8540 llvm::SmallBitVector &CheckedVarArgs,
8541 UncoveredArgHandler &UncoveredArg)
8542 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8543 numDataArgs, beg, APK, Args, formatIdx,
8544 inFunctionCall, CallType, CheckedVarArgs,
8547 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8550 bool allowsObjCArg()
const {
8551 return FSType == FormatStringType::NSString ||
8552 FSType == FormatStringType::OSLog ||
8553 FSType == FormatStringType::OSTrace;
8556 bool HandleInvalidPrintfConversionSpecifier(
8557 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8558 unsigned specifierLen)
override;
8560 void handleInvalidMaskType(StringRef MaskType)
override;
8562 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8563 const char *startSpecifier,
unsigned specifierLen,
8564 const TargetInfo &
Target)
override;
8565 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8566 const char *StartSpecifier,
unsigned SpecifierLen,
8569 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8570 unsigned k,
const char *startSpecifier,
8571 unsigned specifierLen);
8572 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8573 const analyze_printf::OptionalAmount &Amt,
8574 unsigned type,
const char *startSpecifier,
8575 unsigned specifierLen);
8576 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8577 const analyze_printf::OptionalFlag &flag,
8578 const char *startSpecifier,
unsigned specifierLen);
8579 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8580 const analyze_printf::OptionalFlag &ignoredFlag,
8581 const analyze_printf::OptionalFlag &flag,
8582 const char *startSpecifier,
unsigned specifierLen);
8583 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8585 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8586 unsigned flagLen)
override;
8588 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8589 unsigned flagLen)
override;
8592 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8593 const char *flagsEnd,
8594 const char *conversionPosition)
override;
8599class EquatableFormatArgument {
8601 enum SpecifierSensitivity :
unsigned {
8608 enum FormatArgumentRole :
unsigned {
8616 analyze_format_string::ArgType ArgType;
8617 analyze_format_string::LengthModifier LengthMod;
8618 StringRef SpecifierLetter;
8619 CharSourceRange
Range;
8620 SourceLocation ElementLoc;
8621 FormatArgumentRole
Role : 2;
8622 SpecifierSensitivity Sensitivity : 2;
8623 unsigned Position : 14;
8624 unsigned ModifierFor : 14;
8626 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8627 bool InFunctionCall)
const;
8630 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8631 analyze_format_string::LengthModifier LengthMod,
8632 StringRef SpecifierLetter,
8633 analyze_format_string::ArgType ArgType,
8634 FormatArgumentRole
Role,
8635 SpecifierSensitivity Sensitivity,
unsigned Position,
8636 unsigned ModifierFor)
8637 : ArgType(ArgType), LengthMod(LengthMod),
8638 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8639 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8640 ModifierFor(ModifierFor) {}
8642 unsigned getPosition()
const {
return Position; }
8643 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8645 analyze_format_string::LengthModifier getLengthModifier()
const {
8648 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8650 std::string buildFormatSpecifier()
const {
8652 llvm::raw_string_ostream(result)
8653 << getLengthModifier().
toString() << SpecifierLetter;
8657 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8658 const Expr *FmtExpr,
bool InFunctionCall)
const;
8662class DecomposePrintfHandler :
public CheckPrintfHandler {
8663 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8666 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8667 const Expr *origFormatExpr,
8669 unsigned numDataArgs,
bool isObjC,
const char *beg,
8671 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8673 llvm::SmallBitVector &CheckedVarArgs,
8674 UncoveredArgHandler &UncoveredArg,
8675 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8676 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8677 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8678 inFunctionCall, CallType, CheckedVarArgs,
8680 Specs(Specs), HadError(
false) {}
8684 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8686 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8688 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8689 const char *startSpecifier,
8690 unsigned specifierLen,
8691 const TargetInfo &
Target)
override;
8696bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8698 unsigned specifierLen) {
8702 return HandleInvalidConversionSpecifier(
8707void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8708 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8716 return T->isRecordType() ||
T->isComplexType();
8719bool CheckPrintfHandler::HandleAmount(
8721 const char *startSpecifier,
unsigned specifierLen) {
8723 if (HasFormatArguments()) {
8725 if (argIndex >= NumDataArgs) {
8726 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8730 getSpecifierRange(startSpecifier, specifierLen));
8740 CoveredArgs.set(argIndex);
8741 const Expr *Arg = getDataArg(argIndex);
8752 ? diag::err_printf_asterisk_wrong_type
8753 : diag::warn_printf_asterisk_wrong_type;
8754 EmitFormatDiagnostic(S.
PDiag(DiagID)
8759 getSpecifierRange(startSpecifier, specifierLen));
8769void CheckPrintfHandler::HandleInvalidAmount(
8772 const char *startSpecifier,
unsigned specifierLen) {
8782 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8786 getSpecifierRange(startSpecifier, specifierLen), fixit);
8791 const char *startSpecifier,
8792 unsigned specifierLen) {
8796 EmitFormatDiagnostic(
8797 S.
PDiag(diag::warn_printf_nonsensical_flag)
8801 getSpecifierRange(startSpecifier, specifierLen),
8805void CheckPrintfHandler::HandleIgnoredFlag(
8809 unsigned specifierLen) {
8811 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8815 getSpecifierRange(startSpecifier, specifierLen),
8817 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8820void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8823 EmitFormatDiagnostic(
8824 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8825 true, getSpecifierRange(startFlag, flagLen));
8828void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8831 auto Range = getSpecifierRange(startFlag, flagLen);
8832 StringRef flag(startFlag, flagLen);
8833 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8834 getLocationOfByte(startFlag),
8839void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8840 const char *flagsStart,
const char *flagsEnd,
8841 const char *conversionPosition) {
8843 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8844 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8845 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8846 getLocationOfByte(conversionPosition),
8852 const Expr *FmtExpr,
8853 bool InFunctionCall)
const {
8854 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8855 ElementLoc,
true, Range);
8858bool EquatableFormatArgument::VerifyCompatible(
8859 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8860 bool InFunctionCall)
const {
8865 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8866 FmtExpr, InFunctionCall);
8867 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8871 if (
Role != FAR_Data) {
8872 if (ModifierFor !=
Other.ModifierFor) {
8875 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8876 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8877 FmtExpr, InFunctionCall);
8878 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8884 bool HadError =
false;
8885 if (Sensitivity !=
Other.Sensitivity) {
8888 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8889 << Sensitivity <<
Other.Sensitivity,
8890 FmtExpr, InFunctionCall);
8891 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8892 << 0 <<
Other.Range;
8895 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8899 case MK::MatchPromotion:
8903 case MK::NoMatchTypeConfusion:
8904 case MK::NoMatchPromotionTypeConfusion:
8906 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8907 << buildFormatSpecifier()
8908 <<
Other.buildFormatSpecifier(),
8909 FmtExpr, InFunctionCall);
8910 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8911 << 0 <<
Other.Range;
8914 case MK::NoMatchPedantic:
8916 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8917 << buildFormatSpecifier()
8918 <<
Other.buildFormatSpecifier(),
8919 FmtExpr, InFunctionCall);
8920 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8921 << 0 <<
Other.Range;
8924 case MK::NoMatchSignedness:
8926 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8927 << buildFormatSpecifier()
8928 <<
Other.buildFormatSpecifier(),
8929 FmtExpr, InFunctionCall);
8930 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8931 << 0 <<
Other.Range;
8937bool DecomposePrintfHandler::GetSpecifiers(
8938 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8941 StringRef
Data = FSL->getString();
8942 const char *Str =
Data.data();
8943 llvm::SmallBitVector BV;
8944 UncoveredArgHandler UA;
8945 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8946 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8958 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8959 const EquatableFormatArgument &B) {
8960 return A.getPosition() < B.getPosition();
8965bool DecomposePrintfHandler::HandlePrintfSpecifier(
8968 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8983 const unsigned Unset = ~0;
8984 unsigned FieldWidthIndex = Unset;
8985 unsigned PrecisionIndex = Unset;
8989 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8990 FieldWidthIndex = Specs.size();
8992 getSpecifierRange(startSpecifier, specifierLen),
8993 getLocationOfByte(FieldWidth.getStart()),
8995 FieldWidth.getArgType(S.
Context),
8996 EquatableFormatArgument::FAR_FieldWidth,
8997 EquatableFormatArgument::SS_None,
8998 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
9004 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
9005 PrecisionIndex = Specs.size();
9007 getSpecifierRange(startSpecifier, specifierLen),
9008 getLocationOfByte(Precision.getStart()),
9010 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
9011 EquatableFormatArgument::SS_None,
9012 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
9018 unsigned SpecIndex =
9020 if (FieldWidthIndex != Unset)
9021 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
9022 if (PrecisionIndex != Unset)
9023 Specs[PrecisionIndex].setModifierFor(SpecIndex);
9025 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
9027 Sensitivity = EquatableFormatArgument::SS_Private;
9029 Sensitivity = EquatableFormatArgument::SS_Public;
9031 Sensitivity = EquatableFormatArgument::SS_Sensitive;
9033 Sensitivity = EquatableFormatArgument::SS_None;
9036 getSpecifierRange(startSpecifier, specifierLen),
9039 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
9044 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
9049 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
9050 SpecIndex + 1, SpecIndex);
9058template<
typename MemberKind>
9069 R.suppressDiagnostics();
9076 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
9091 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9093 if ((*MI)->getMinRequiredArguments() == 0)
9101bool CheckPrintfHandler::checkForCStrMembers(
9108 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9111 if (
Method->getMinRequiredArguments() == 0 &&
9124bool CheckPrintfHandler::HandlePrintfSpecifier(
9137 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9138 startSpecifier, specifierLen);
9150 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9155 if (!CS.consumesDataArgument()) {
9163 if (argIndex < NumDataArgs) {
9167 CoveredArgs.set(argIndex);
9174 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9177 if (HasFormatArguments()) {
9179 CoveredArgs.set(argIndex + 1);
9182 const Expr *Ex = getDataArg(argIndex);
9186 : ArgType::CPointerTy;
9188 EmitFormatDiagnostic(
9189 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9193 getSpecifierRange(startSpecifier, specifierLen));
9196 Ex = getDataArg(argIndex + 1);
9199 EmitFormatDiagnostic(
9200 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9204 getSpecifierRange(startSpecifier, specifierLen));
9211 if (!allowsObjCArg() && CS.isObjCArg()) {
9212 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9219 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9226 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9227 getLocationOfByte(CS.getStart()),
9229 getSpecifierRange(startSpecifier, specifierLen));
9239 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9246 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9250 getSpecifierRange(startSpecifier, specifierLen));
9253 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9257 getSpecifierRange(startSpecifier, specifierLen));
9261 const llvm::Triple &Triple =
Target.getTriple();
9263 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9264 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9265 getLocationOfByte(CS.getStart()),
9267 getSpecifierRange(startSpecifier, specifierLen));
9273 startSpecifier, specifierLen);
9279 startSpecifier, specifierLen);
9285 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9286 getLocationOfByte(startSpecifier),
9288 getSpecifierRange(startSpecifier, specifierLen));
9297 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9299 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9308 startSpecifier, specifierLen);
9311 startSpecifier, specifierLen);
9316 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9317 diag::warn_format_nonsensical_length);
9319 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9321 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9322 diag::warn_format_non_standard_conversion_spec);
9325 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9328 if (!HasFormatArguments())
9331 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9334 const Expr *Arg = getDataArg(argIndex);
9338 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9350 case Stmt::ArraySubscriptExprClass:
9351 case Stmt::CallExprClass:
9352 case Stmt::CharacterLiteralClass:
9353 case Stmt::CXXBoolLiteralExprClass:
9354 case Stmt::DeclRefExprClass:
9355 case Stmt::FloatingLiteralClass:
9356 case Stmt::IntegerLiteralClass:
9357 case Stmt::MemberExprClass:
9358 case Stmt::ObjCArrayLiteralClass:
9359 case Stmt::ObjCBoolLiteralExprClass:
9360 case Stmt::ObjCBoxedExprClass:
9361 case Stmt::ObjCDictionaryLiteralClass:
9362 case Stmt::ObjCEncodeExprClass:
9363 case Stmt::ObjCIvarRefExprClass:
9364 case Stmt::ObjCMessageExprClass:
9365 case Stmt::ObjCPropertyRefExprClass:
9366 case Stmt::ObjCStringLiteralClass:
9367 case Stmt::ObjCSubscriptRefExprClass:
9368 case Stmt::ParenExprClass:
9369 case Stmt::StringLiteralClass:
9370 case Stmt::UnaryOperatorClass:
9377static std::pair<QualType, StringRef>
9383 StringRef Name = UserTy->getDecl()->getName();
9384 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9385 .Case(
"CFIndex", Context.getNSIntegerType())
9386 .Case(
"NSInteger", Context.getNSIntegerType())
9387 .Case(
"NSUInteger", Context.getNSUIntegerType())
9388 .Case(
"SInt32", Context.IntTy)
9389 .Case(
"UInt32", Context.UnsignedIntTy)
9393 return std::make_pair(CastTy, Name);
9395 TyTy = UserTy->desugar();
9399 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9409 StringRef TrueName, FalseName;
9412 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9414 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9416 if (TrueTy == FalseTy)
9417 return std::make_pair(TrueTy, TrueName);
9418 else if (TrueTy.
isNull())
9419 return std::make_pair(FalseTy, FalseName);
9420 else if (FalseTy.
isNull())
9421 return std::make_pair(TrueTy, TrueName);
9424 return std::make_pair(
QualType(), StringRef());
9443 From = VecTy->getElementType();
9445 To = VecTy->getElementType();
9456 diag::warn_format_conversion_argument_type_mismatch_signedness,
9460 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9467bool CheckPrintfHandler::checkFormatExpr(
9469 unsigned SpecifierLen,
const Expr *E) {
9480 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9481 ExprTy = TET->getUnderlyingExpr()->getType();
9484 if (
const OverflowBehaviorType *OBT =
9486 ExprTy = OBT->getUnderlyingType();
9500 getSpecifierRange(StartSpecifier, SpecifierLen);
9502 llvm::raw_svector_ostream os(FSString);
9504 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9515 getSpecifierRange(StartSpecifier, SpecifierLen);
9516 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9521 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9529 if (
Match == ArgType::Match)
9533 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9542 E = ICE->getSubExpr();
9552 if (OrigMatch == ArgType::NoMatchSignedness &&
9553 ImplicitMatch != ArgType::NoMatchSignedness)
9560 if (ImplicitMatch == ArgType::Match)
9578 if (
Match == ArgType::MatchPromotion)
9582 if (
Match == ArgType::MatchPromotion) {
9586 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9587 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9591 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9592 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9593 Match = ImplicitMatch;
9594 assert(
Match != ArgType::MatchPromotion);
9597 bool IsEnum =
false;
9598 bool IsScopedEnum =
false;
9601 IntendedTy = ED->getIntegerType();
9602 if (!ED->isScoped()) {
9603 ExprTy = IntendedTy;
9608 IsScopedEnum =
true;
9615 if (isObjCContext() &&
9626 const llvm::APInt &
V = IL->getValue();
9636 if (TD->getUnderlyingType() == IntendedTy)
9646 bool ShouldNotPrintDirectly =
false;
9647 StringRef CastTyName;
9650 std::tie(CastTy, CastTyName) =
9656 if (!IsScopedEnum &&
9657 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9661 IntendedTy = CastTy;
9662 ShouldNotPrintDirectly =
true;
9667 PrintfSpecifier fixedFS = FS;
9674 llvm::raw_svector_ostream os(buf);
9677 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9679 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9685 llvm_unreachable(
"expected non-matching");
9687 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9690 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9693 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9696 Diag = diag::warn_format_conversion_argument_type_mismatch;
9717 llvm::raw_svector_ostream CastFix(CastBuf);
9718 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9720 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9726 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9731 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9753 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9759 Name = TypedefTy->getDecl()->getName();
9763 ? diag::warn_format_argument_needs_cast_pedantic
9764 : diag::warn_format_argument_needs_cast;
9765 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9776 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9777 : diag::warn_format_conversion_argument_type_mismatch;
9779 EmitFormatDiagnostic(
9787 getSpecifierRange(StartSpecifier, SpecifierLen);
9791 bool EmitTypeMismatch =
false;
9795 bool EmitOSLogError =
false;
9804 llvm_unreachable(
"expected non-matching");
9806 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9809 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9812 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9816 Diag = diag::warn_format_conversion_argument_type_mismatch;
9820 if (!EmitOSLogError)
9821 EmitFormatDiagnostic(
9830 EmitTypeMismatch =
true;
9834 EmitOSLogError =
true;
9836 EmitFormatDiagnostic(
9837 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9838 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9842 checkForCStrMembers(AT, E);
9848 EmitTypeMismatch =
true;
9850 EmitFormatDiagnostic(
9851 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9852 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9866 EmitFormatDiagnostic(
9867 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
9872 if (EmitTypeMismatch) {
9878 EmitFormatDiagnostic(
9879 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9885 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9886 "format string specifier index out of range");
9887 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9897class CheckScanfHandler :
public CheckFormatHandler {
9899 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
9901 unsigned firstDataArg,
unsigned numDataArgs,
9903 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9905 llvm::SmallBitVector &CheckedVarArgs,
9906 UncoveredArgHandler &UncoveredArg)
9907 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
9908 numDataArgs, beg, APK, Args, formatIdx,
9909 inFunctionCall, CallType, CheckedVarArgs,
9912 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9913 const char *startSpecifier,
9914 unsigned specifierLen)
override;
9917 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9918 const char *startSpecifier,
9919 unsigned specifierLen)
override;
9921 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9926void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9928 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9929 getLocationOfByte(end),
true,
9930 getSpecifierRange(start, end - start));
9933bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9935 unsigned specifierLen) {
9939 return HandleInvalidConversionSpecifier(
9944bool CheckScanfHandler::HandleScanfSpecifier(
9946 unsigned specifierLen) {
9959 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9960 startSpecifier, specifierLen);
9971 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9986 if (argIndex < NumDataArgs) {
9990 CoveredArgs.set(argIndex);
9996 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9997 diag::warn_format_nonsensical_length);
9999 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
10001 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10002 diag::warn_format_non_standard_conversion_spec);
10005 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
10008 if (!HasFormatArguments())
10011 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
10015 const Expr *Ex = getDataArg(argIndex);
10025 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
10036 ScanfSpecifier fixedFS = FS;
10041 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
10043 ? diag::warn_format_conversion_argument_type_mismatch_signedness
10044 : diag::warn_format_conversion_argument_type_mismatch;
10049 llvm::raw_svector_ostream os(buf);
10052 EmitFormatDiagnostic(
10057 getSpecifierRange(startSpecifier, specifierLen),
10059 getSpecifierRange(startSpecifier, specifierLen), os.str()));
10066 getSpecifierRange(startSpecifier, specifierLen));
10076 const Expr *FmtExpr,
bool InFunctionCall) {
10077 bool HadError =
false;
10078 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
10079 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
10080 while (FmtIter < FmtEnd && RefIter < RefEnd) {
10092 for (; FmtIter < FmtEnd; ++FmtIter) {
10096 if (FmtIter->getPosition() < RefIter->getPosition())
10100 if (FmtIter->getPosition() > RefIter->getPosition())
10104 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
10108 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
10109 return Arg.getPosition() != RefIter->getPosition();
10113 if (FmtIter < FmtEnd) {
10114 CheckFormatHandler::EmitFormatDiagnostic(
10115 S, InFunctionCall, FmtExpr,
10116 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
10117 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
10118 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
10119 }
else if (RefIter < RefEnd) {
10120 CheckFormatHandler::EmitFormatDiagnostic(
10121 S, InFunctionCall, FmtExpr,
10122 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
10125 << 1 << RefIter->getSourceRange();
10131 Sema &S,
const FormatStringLiteral *FExpr,
10136 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10137 bool IgnoreStringsWithoutSpecifiers) {
10139 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10140 CheckFormatHandler::EmitFormatDiagnostic(
10141 S, inFunctionCall, Args[format_idx],
10142 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10148 StringRef StrRef = FExpr->getString();
10149 const char *Str = StrRef.data();
10153 assert(
T &&
"String literal not of constant array type!");
10154 size_t TypeSize =
T->getZExtSize();
10155 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10156 const unsigned numDataArgs = Args.size() - firstDataArg;
10158 if (IgnoreStringsWithoutSpecifiers &&
10165 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10166 CheckFormatHandler::EmitFormatDiagnostic(
10167 S, inFunctionCall, Args[format_idx],
10168 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10169 FExpr->getBeginLoc(),
10175 if (StrLen == 0 && numDataArgs > 0) {
10176 CheckFormatHandler::EmitFormatDiagnostic(
10177 S, inFunctionCall, Args[format_idx],
10178 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10189 if (ReferenceFormatString ==
nullptr) {
10190 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10191 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10192 inFunctionCall, CallType, CheckedVarArgs,
10199 H.DoneProcessing();
10202 Type, ReferenceFormatString, FExpr->getFormatString(),
10203 inFunctionCall ?
nullptr : Args[format_idx]);
10206 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10207 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10208 CallType, CheckedVarArgs, UncoveredArg);
10212 H.DoneProcessing();
10228 FormatStringLiteral RefLit = AuthoritativeFormatString;
10229 FormatStringLiteral TestLit = TestedFormatString;
10231 bool DiagAtStringLiteral;
10232 if (FunctionCallArg) {
10233 Arg = FunctionCallArg;
10234 DiagAtStringLiteral =
false;
10236 Arg = TestedFormatString;
10237 DiagAtStringLiteral =
true;
10239 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10240 AuthoritativeFormatString,
Type,
10241 IsObjC,
true, RefArgs) &&
10242 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10243 DiagAtStringLiteral, FmtArgs)) {
10245 TestedFormatString, FmtArgs, Arg,
10246 DiagAtStringLiteral);
10259 FormatStringLiteral RefLit = Str;
10263 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10272 bool HadError =
false;
10273 auto Iter = Args.begin();
10274 auto End = Args.end();
10275 while (Iter != End) {
10276 const auto &FirstInGroup = *Iter;
10278 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10280 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10289 const char *Str = StrRef.data();
10292 assert(
T &&
"String literal not of constant array type!");
10293 size_t TypeSize =
T->getZExtSize();
10294 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10304 switch (AbsFunction) {
10308 case Builtin::BI__builtin_abs:
10309 return Builtin::BI__builtin_labs;
10310 case Builtin::BI__builtin_labs:
10311 return Builtin::BI__builtin_llabs;
10312 case Builtin::BI__builtin_llabs:
10315 case Builtin::BI__builtin_fabsf:
10316 return Builtin::BI__builtin_fabs;
10317 case Builtin::BI__builtin_fabs:
10318 return Builtin::BI__builtin_fabsl;
10319 case Builtin::BI__builtin_fabsl:
10322 case Builtin::BI__builtin_cabsf:
10323 return Builtin::BI__builtin_cabs;
10324 case Builtin::BI__builtin_cabs:
10325 return Builtin::BI__builtin_cabsl;
10326 case Builtin::BI__builtin_cabsl:
10329 case Builtin::BIabs:
10330 return Builtin::BIlabs;
10331 case Builtin::BIlabs:
10332 return Builtin::BIllabs;
10333 case Builtin::BIllabs:
10336 case Builtin::BIfabsf:
10337 return Builtin::BIfabs;
10338 case Builtin::BIfabs:
10339 return Builtin::BIfabsl;
10340 case Builtin::BIfabsl:
10343 case Builtin::BIcabsf:
10344 return Builtin::BIcabs;
10345 case Builtin::BIcabs:
10346 return Builtin::BIcabsl;
10347 case Builtin::BIcabsl:
10354 unsigned AbsType) {
10376 unsigned AbsFunctionKind) {
10377 unsigned BestKind = 0;
10378 uint64_t ArgSize = Context.getTypeSize(ArgType);
10379 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10382 if (Context.getTypeSize(ParamType) >= ArgSize) {
10385 else if (Context.hasSameType(ParamType, ArgType)) {
10401 if (
T->isIntegralOrEnumerationType())
10403 if (
T->isRealFloatingType())
10405 if (
T->isAnyComplexType())
10408 llvm_unreachable(
"Type not integer, floating, or complex");
10415 switch (ValueKind) {
10420 case Builtin::BI__builtin_fabsf:
10421 case Builtin::BI__builtin_fabs:
10422 case Builtin::BI__builtin_fabsl:
10423 case Builtin::BI__builtin_cabsf:
10424 case Builtin::BI__builtin_cabs:
10425 case Builtin::BI__builtin_cabsl:
10426 return Builtin::BI__builtin_abs;
10427 case Builtin::BIfabsf:
10428 case Builtin::BIfabs:
10429 case Builtin::BIfabsl:
10430 case Builtin::BIcabsf:
10431 case Builtin::BIcabs:
10432 case Builtin::BIcabsl:
10433 return Builtin::BIabs;
10439 case Builtin::BI__builtin_abs:
10440 case Builtin::BI__builtin_labs:
10441 case Builtin::BI__builtin_llabs:
10442 case Builtin::BI__builtin_cabsf:
10443 case Builtin::BI__builtin_cabs:
10444 case Builtin::BI__builtin_cabsl:
10445 return Builtin::BI__builtin_fabsf;
10446 case Builtin::BIabs:
10447 case Builtin::BIlabs:
10448 case Builtin::BIllabs:
10449 case Builtin::BIcabsf:
10450 case Builtin::BIcabs:
10451 case Builtin::BIcabsl:
10452 return Builtin::BIfabsf;
10458 case Builtin::BI__builtin_abs:
10459 case Builtin::BI__builtin_labs:
10460 case Builtin::BI__builtin_llabs:
10461 case Builtin::BI__builtin_fabsf:
10462 case Builtin::BI__builtin_fabs:
10463 case Builtin::BI__builtin_fabsl:
10464 return Builtin::BI__builtin_cabsf;
10465 case Builtin::BIabs:
10466 case Builtin::BIlabs:
10467 case Builtin::BIllabs:
10468 case Builtin::BIfabsf:
10469 case Builtin::BIfabs:
10470 case Builtin::BIfabsl:
10471 return Builtin::BIcabsf;
10474 llvm_unreachable(
"Unable to convert function");
10485 case Builtin::BI__builtin_abs:
10486 case Builtin::BI__builtin_fabs:
10487 case Builtin::BI__builtin_fabsf:
10488 case Builtin::BI__builtin_fabsl:
10489 case Builtin::BI__builtin_labs:
10490 case Builtin::BI__builtin_llabs:
10491 case Builtin::BI__builtin_cabs:
10492 case Builtin::BI__builtin_cabsf:
10493 case Builtin::BI__builtin_cabsl:
10494 case Builtin::BIabs:
10495 case Builtin::BIlabs:
10496 case Builtin::BIllabs:
10497 case Builtin::BIfabs:
10498 case Builtin::BIfabsf:
10499 case Builtin::BIfabsl:
10500 case Builtin::BIcabs:
10501 case Builtin::BIcabsf:
10502 case Builtin::BIcabsl:
10505 llvm_unreachable(
"Unknown Builtin type");
10511 unsigned AbsKind,
QualType ArgType) {
10512 bool EmitHeaderHint =
true;
10513 const char *HeaderName =
nullptr;
10514 std::string FunctionName;
10515 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10516 FunctionName =
"std::abs";
10517 if (ArgType->isIntegralOrEnumerationType()) {
10518 HeaderName =
"cstdlib";
10519 }
else if (ArgType->isRealFloatingType()) {
10520 HeaderName =
"cmath";
10522 llvm_unreachable(
"Invalid Type");
10528 R.suppressDiagnostics();
10531 for (
const auto *I : R) {
10534 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10536 FDecl = dyn_cast<FunctionDecl>(I);
10551 EmitHeaderHint =
false;
10563 R.suppressDiagnostics();
10566 if (R.isSingleResult()) {
10567 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10569 EmitHeaderHint =
false;
10573 }
else if (!R.empty()) {
10579 S.
Diag(Loc, diag::note_replace_abs_function)
10585 if (!EmitHeaderHint)
10588 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10592template <std::
size_t StrLen>
10594 const char (&Str)[StrLen]) {
10607 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10608 return llvm::is_contained(names, calleeName);
10613 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10614 "__builtin_nanf16",
"__builtin_nanf128"});
10616 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10617 "__builtin_inff16",
"__builtin_inff128"});
10619 llvm_unreachable(
"unknown MathCheck");
10623 if (FDecl->
getName() !=
"infinity")
10626 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10628 if (RDecl->
getName() !=
"numeric_limits")
10645 if (FPO.getNoHonorNaNs() &&
10648 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10649 << 1 << 0 <<
Call->getSourceRange();
10653 if (FPO.getNoHonorInfs() &&
10657 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10658 << 0 << 0 <<
Call->getSourceRange();
10662void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10664 if (
Call->getNumArgs() != 1)
10669 if (AbsKind == 0 && !IsStdAbs)
10672 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10673 QualType ParamType =
Call->getArg(0)->getType();
10678 std::string FunctionName =
10679 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10680 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10681 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10716 if (ArgValueKind == ParamValueKind) {
10717 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10721 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10722 << FDecl << ArgType << ParamType;
10724 if (NewAbsKind == 0)
10728 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10737 if (NewAbsKind == 0)
10740 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10741 << FDecl << ParamValueKind << ArgValueKind;
10744 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10750 if (!
Call || !FDecl)
return;
10754 if (
Call->getExprLoc().isMacroID())
return;
10757 if (
Call->getNumArgs() != 2)
return;
10760 if (!ArgList)
return;
10761 if (ArgList->size() != 1)
return;
10764 const auto& TA = ArgList->
get(0);
10766 QualType ArgType = TA.getAsType();
10770 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10771 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10772 if (!MTE)
return false;
10773 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10774 if (!
Num)
return false;
10775 if (
Num->getValue() != 0)
return false;
10779 const Expr *FirstArg =
Call->getArg(0);
10780 const Expr *SecondArg =
Call->getArg(1);
10781 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10782 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10785 if (IsFirstArgZero == IsSecondArgZero)
return;
10790 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10792 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10793 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10796 SourceRange RemovalRange;
10797 if (IsFirstArgZero) {
10798 RemovalRange = SourceRange(FirstRange.
getBegin(),
10805 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10820 const auto *Size = dyn_cast<BinaryOperator>(E);
10825 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10829 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10830 << SizeRange << FnName;
10831 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10836 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10847 bool &IsContained) {
10849 const Type *Ty =
T->getBaseElementTypeUnsafe();
10850 IsContained =
false;
10863 for (
auto *FD : RD->
fields()) {
10867 IsContained =
true;
10868 return ContainedRD;
10876 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10877 if (Unary->getKind() == UETT_SizeOf)
10886 if (!
SizeOf->isArgumentType())
10887 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10894 return SizeOf->getTypeOfArgument();
10900struct SearchNonTrivialToInitializeField
10903 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10905 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10908 SourceLocation SL) {
10909 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10910 asDerived().visitArray(PDIK, AT, SL);
10914 Super::visitWithKind(PDIK, FT, SL);
10917 void visitARCStrong(QualType FT, SourceLocation SL) {
10920 void visitARCWeak(QualType FT, SourceLocation SL) {
10923 void visitStruct(QualType FT, SourceLocation SL) {
10928 const ArrayType *AT, SourceLocation SL) {
10929 visit(getContext().getBaseElementType(AT), SL);
10931 void visitTrivial(QualType FT, SourceLocation SL) {}
10933 static void diag(QualType RT,
const Expr *E, Sema &S) {
10934 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10943struct SearchNonTrivialToCopyField
10945 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10947 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10950 SourceLocation SL) {
10951 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10952 asDerived().visitArray(PCK, AT, SL);
10956 Super::visitWithKind(PCK, FT, SL);
10959 void visitARCStrong(QualType FT, SourceLocation SL) {
10962 void visitARCWeak(QualType FT, SourceLocation SL) {
10965 void visitPtrAuth(QualType FT, SourceLocation SL) {
10968 void visitStruct(QualType FT, SourceLocation SL) {
10973 SourceLocation SL) {
10974 visit(getContext().getBaseElementType(AT), SL);
10977 SourceLocation SL) {}
10978 void visitTrivial(QualType FT, SourceLocation SL) {}
10979 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10981 static void diag(QualType RT,
const Expr *E, Sema &S) {
10982 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10997 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10998 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
11031 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
11034 const Expr *SizeArg =
11035 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
11037 auto isLiteralZero = [](
const Expr *E) {
11047 if (isLiteralZero(SizeArg) &&
11054 if (BId == Builtin::BIbzero ||
11057 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
11058 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
11059 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
11060 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
11061 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
11069 if (BId == Builtin::BImemset &&
11073 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
11074 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
11079void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
11086 unsigned ExpectedNumArgs =
11087 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
11088 if (
Call->getNumArgs() < ExpectedNumArgs)
11091 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
11092 BId == Builtin::BIstrndup ? 1 : 2);
11094 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
11098 Call->getBeginLoc(),
Call->getRParenLoc()))
11110 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
11111 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
11114 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
11118 QualType DestTy = Dest->
getType();
11119 QualType PointeeTy;
11120 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11132 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11138 if (SizeOfArgTy != QualType()) {
11140 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11142 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11143 << FnName << SizeOfArgTy << ArgIdx
11150 PointeeTy = DestTy;
11153 if (PointeeTy == QualType())
11158 if (
const CXXRecordDecl *ContainedRD =
11161 unsigned OperationType = 0;
11162 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11165 if (ArgIdx != 0 || IsCmp) {
11166 if (BId == Builtin::BImemcpy)
11168 else if(BId == Builtin::BImemmove)
11175 PDiag(diag::warn_dyn_class_memaccess)
11176 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11177 << IsContained << ContainedRD << OperationType
11178 <<
Call->getCallee()->getSourceRange());
11180 BId != Builtin::BImemset)
11183 PDiag(diag::warn_arc_object_memaccess)
11184 << ArgIdx << FnName << PointeeTy
11185 <<
Call->getCallee()->getSourceRange());
11192 bool NonTriviallyCopyableCXXRecord =
11196 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11199 PDiag(diag::warn_cstruct_memaccess)
11200 << ArgIdx << FnName << PointeeTy << 0);
11201 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11202 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11203 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11207 PDiag(diag::warn_cxxstruct_memaccess)
11208 << FnName << PointeeTy);
11209 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11212 PDiag(diag::warn_cstruct_memaccess)
11213 << ArgIdx << FnName << PointeeTy << 1);
11214 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11215 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11216 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11220 PDiag(diag::warn_cxxstruct_memaccess)
11221 << FnName << PointeeTy);
11230 PDiag(diag::note_bad_memaccess_silence)
11236bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11238 llvm::FoldingSetNodeID SizeOfArgID;
11244 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11247 QualType DestTy = Dest->
getType();
11248 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11254 if (SizeOfArgID == llvm::FoldingSetNodeID())
11257 llvm::FoldingSetNodeID DestID;
11259 if (DestID == SizeOfArgID) {
11262 unsigned ActionIdx = 0;
11263 StringRef ReadableName = FnName->
getName();
11265 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11266 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11275 SourceLocation SL = SizeOfArg->
getExprLoc();
11290 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11291 << ReadableName << PointeeTy << DestTy << DSR
11294 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11295 << ActionIdx << SSR);
11331 if (CAT->getZExtSize() <= 1)
11339void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11343 unsigned NumArgs =
Call->getNumArgs();
11344 if ((NumArgs != 3) && (NumArgs != 4))
11349 const Expr *CompareWithSrc =
nullptr;
11352 Call->getBeginLoc(),
Call->getRParenLoc()))
11357 CompareWithSrc = Ex;
11360 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11361 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11362 SizeCall->getNumArgs() == 1)
11367 if (!CompareWithSrc)
11374 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11378 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11379 if (!CompareWithSrcDRE ||
11383 const Expr *OriginalSizeArg =
Call->getArg(2);
11384 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11391 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11395 SmallString<128> sizeString;
11396 llvm::raw_svector_ostream
OS(sizeString);
11401 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11408 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11409 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11410 return D1->getDecl() == D2->getDecl();
11415 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11424void Sema::CheckStrncatArguments(
const CallExpr *CE,
11439 unsigned PatternType = 0;
11447 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11448 if (BE->getOpcode() == BO_Sub) {
11449 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11450 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11461 if (PatternType == 0)
11477 QualType DstTy = DstArg->
getType();
11480 if (!isKnownSizeArray) {
11481 if (PatternType == 1)
11482 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11484 Diag(SL, diag::warn_strncat_src_size) << SR;
11488 if (PatternType == 1)
11489 Diag(SL, diag::warn_strncat_large_size) << SR;
11491 Diag(SL, diag::warn_strncat_src_size) << SR;
11493 SmallString<128> sizeString;
11494 llvm::raw_svector_ostream
OS(sizeString);
11502 Diag(SL, diag::note_strncat_wrong_size)
11507void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11516void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11518 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11519 const Decl *D = Lvalue->getDecl();
11520 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11521 if (!DD->getType()->isReferenceType())
11522 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11526 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11527 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11528 Lvalue->getMemberDecl());
11531void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11533 const auto *Lambda = dyn_cast<LambdaExpr>(
11538 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11539 << CalleeName << 2 ;
11542void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11544 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11545 if (Var ==
nullptr)
11549 << CalleeName << 0 << Var;
11552void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11555 llvm::raw_svector_ostream
OS(SizeString);
11558 if (Kind == clang::CK_BitCast &&
11559 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11561 if (Kind == clang::CK_IntegralToPointer &&
11563 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11566 switch (
Cast->getCastKind()) {
11567 case clang::CK_BitCast:
11568 case clang::CK_IntegralToPointer:
11569 case clang::CK_FunctionToPointerDecay:
11578 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11579 << CalleeName << 0 <<
OS.str();
11583void Sema::CheckFreeArguments(
const CallExpr *E) {
11584 const std::string CalleeName =
11589 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11591 case UnaryOperator::Opcode::UO_AddrOf:
11592 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11593 case UnaryOperator::Opcode::UO_Plus:
11594 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11599 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11601 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11603 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11604 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11605 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11611 << CalleeName << 1 ;
11616 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11617 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11621Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11630 Diag(ReturnLoc, diag::warn_null_ret)
11640 if (Op == OO_New || Op == OO_Array_New) {
11641 const FunctionProtoType *Proto
11645 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11651 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11656 if (
Context.getTargetInfo().getTriple().isPPC64())
11668 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11669 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11670 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11671 return FPLiteral && FPCast;
11674 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11680 llvm::APFloat TargetC = FPLiteral->
getValue();
11681 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11682 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11686 Diag(Loc, diag::warn_float_compare_literal)
11687 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11700 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11701 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11702 if (DRL->getDecl() == DRR->getDecl())
11710 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11711 if (FLL->isExact())
11713 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11714 if (FLR->isExact())
11718 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11719 CL &&
CL->getBuiltinCallee())
11722 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11723 CR && CR->getBuiltinCallee())
11727 Diag(Loc, diag::warn_floatingpoint_eq)
11748 IntRange(
unsigned Width,
bool NonNegative)
11749 : Width(Width), NonNegative(NonNegative) {}
11752 unsigned valueBits()
const {
11753 return NonNegative ? Width : Width - 1;
11757 static IntRange forBoolType() {
11758 return IntRange(1,
true);
11762 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11763 return forValueOfCanonicalType(
C,
11768 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11771 if (
const auto *VT = dyn_cast<VectorType>(
T))
11772 T = VT->getElementType().getTypePtr();
11773 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11774 T = MT->getElementType().getTypePtr();
11775 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11776 T = CT->getElementType().getTypePtr();
11777 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11778 T = AT->getValueType().getTypePtr();
11779 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11780 T = OBT->getUnderlyingType().getTypePtr();
11782 if (!
C.getLangOpts().CPlusPlus) {
11785 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11790 if (
Enum->isFixed()) {
11791 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11792 !
Enum->getIntegerType()->isSignedIntegerType());
11795 unsigned NumPositive =
Enum->getNumPositiveBits();
11796 unsigned NumNegative =
Enum->getNumNegativeBits();
11798 if (NumNegative == 0)
11799 return IntRange(NumPositive,
true);
11801 return IntRange(std::max(NumPositive + 1, NumNegative),
11805 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11806 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11819 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11822 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11823 T = VT->getElementType().getTypePtr();
11824 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11825 T = MT->getElementType().getTypePtr();
11826 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11827 T = CT->getElementType().getTypePtr();
11828 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11829 T = AT->getValueType().getTypePtr();
11831 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11832 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11833 T = OBT->getUnderlyingType().getTypePtr();
11835 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11836 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11845 static IntRange
join(IntRange L, IntRange R) {
11846 bool Unsigned = L.NonNegative &&
R.NonNegative;
11847 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11848 L.NonNegative &&
R.NonNegative);
11852 static IntRange bit_and(IntRange L, IntRange R) {
11853 unsigned Bits = std::max(L.Width,
R.Width);
11854 bool NonNegative =
false;
11855 if (L.NonNegative) {
11856 Bits = std::min(Bits, L.Width);
11857 NonNegative =
true;
11859 if (
R.NonNegative) {
11860 Bits = std::min(Bits,
R.Width);
11861 NonNegative =
true;
11863 return IntRange(Bits, NonNegative);
11867 static IntRange sum(IntRange L, IntRange R) {
11868 bool Unsigned = L.NonNegative &&
R.NonNegative;
11869 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11874 static IntRange difference(IntRange L, IntRange R) {
11878 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11879 bool Unsigned = L.NonNegative &&
R.Width == 0;
11880 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11886 static IntRange product(IntRange L, IntRange R) {
11890 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11891 bool Unsigned = L.NonNegative &&
R.NonNegative;
11892 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11897 static IntRange rem(IntRange L, IntRange R) {
11901 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11909 if (value.isSigned() && value.isNegative())
11910 return IntRange(value.getSignificantBits(),
false);
11912 if (value.getBitWidth() > MaxWidth)
11913 value = value.trunc(MaxWidth);
11917 return IntRange(value.getActiveBits(),
true);
11921 if (result.
isInt())
11928 R = IntRange::join(R, El);
11936 return IntRange::join(R, I);
11951 Ty = AtomicRHS->getValueType();
11970 bool InConstantContext,
11971 bool Approximate) {
11982 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11983 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11987 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11989 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11990 CE->getCastKind() == CK_BooleanToSignedIntegral;
11993 if (!isIntegerCast)
11994 return OutputTypeRange;
11997 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11998 InConstantContext, Approximate);
12000 return std::nullopt;
12003 if (SubRange->Width >= OutputTypeRange.Width)
12004 return OutputTypeRange;
12008 return IntRange(SubRange->Width,
12009 SubRange->NonNegative || OutputTypeRange.NonNegative);
12012 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12015 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
12017 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
12018 InConstantContext, Approximate);
12023 Expr *TrueExpr = CO->getTrueExpr();
12025 return std::nullopt;
12027 std::optional<IntRange> L =
12030 return std::nullopt;
12032 Expr *FalseExpr = CO->getFalseExpr();
12034 return std::nullopt;
12036 std::optional<IntRange> R =
12039 return std::nullopt;
12041 return IntRange::join(*L, *R);
12044 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12045 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
12047 switch (BO->getOpcode()) {
12049 llvm_unreachable(
"builtin <=> should have class type");
12060 return IntRange::forBoolType();
12089 Combine = IntRange::bit_and;
12097 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
12098 if (I->getValue() == 1) {
12099 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
12100 return IntRange(R.Width,
true);
12110 case BO_ShrAssign: {
12112 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
12114 return std::nullopt;
12118 if (std::optional<llvm::APSInt> shift =
12119 BO->getRHS()->getIntegerConstantExpr(
C)) {
12120 if (shift->isNonNegative()) {
12121 if (shift->uge(L->Width))
12122 L->Width = (L->NonNegative ? 0 : 1);
12124 L->Width -= shift->getZExtValue();
12138 Combine = IntRange::sum;
12142 if (BO->getLHS()->getType()->isPointerType())
12145 Combine = IntRange::difference;
12150 Combine = IntRange::product;
12159 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12161 return std::nullopt;
12164 if (std::optional<llvm::APSInt> divisor =
12165 BO->getRHS()->getIntegerConstantExpr(
C)) {
12166 unsigned log2 = divisor->logBase2();
12167 if (
log2 >= L->Width)
12168 L->Width = (L->NonNegative ? 0 : 1);
12170 L->Width = std::min(L->Width -
log2, MaxWidth);
12178 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12180 return std::nullopt;
12182 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12186 Combine = IntRange::rem;
12198 unsigned opWidth =
C.getIntWidth(
T);
12200 InConstantContext, Approximate);
12202 return std::nullopt;
12205 InConstantContext, Approximate);
12207 return std::nullopt;
12209 IntRange
C = Combine(*L, *R);
12210 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
12211 C.Width = std::min(
C.Width, MaxWidth);
12215 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12216 switch (UO->getOpcode()) {
12219 return IntRange::forBoolType();
12233 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12236 return std::nullopt;
12241 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12251 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12254 return std::nullopt;
12259 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12269 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) {
12273 if (
const Expr *SourceExpr = OVE->getSourceExpr())
12279 return IntRange(BitField->getBitWidthValue(),
12280 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12283 return std::nullopt;
12289 bool InConstantContext,
12290 bool Approximate) {
12299 const llvm::fltSemantics &Src,
12300 const llvm::fltSemantics &Tgt) {
12301 llvm::APFloat truncated = value;
12304 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12305 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12307 return truncated.bitwiseIsEqual(value);
12316 const llvm::fltSemantics &Src,
12317 const llvm::fltSemantics &Tgt) {
12341 bool IsListInit =
false);
12356 return MacroName !=
"YES" && MacroName !=
"NO" &&
12357 MacroName !=
"true" && MacroName !=
"false";
12365 (!E->
getType()->isSignedIntegerType() ||
12380struct PromotedRange {
12382 llvm::APSInt PromotedMin;
12384 llvm::APSInt PromotedMax;
12386 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12388 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12389 else if (
R.Width >= BitWidth && !
Unsigned) {
12393 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12394 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12396 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12397 .extOrTrunc(BitWidth);
12398 PromotedMin.setIsUnsigned(
Unsigned);
12400 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12401 .extOrTrunc(BitWidth);
12402 PromotedMax.setIsUnsigned(
Unsigned);
12407 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12417 InRangeFlag = 0x40,
12420 Min =
LE | InRangeFlag,
12421 InRange = InRangeFlag,
12422 Max =
GE | InRangeFlag,
12425 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12430 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12431 Value.isUnsigned() == PromotedMin.isUnsigned());
12432 if (!isContiguous()) {
12433 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12434 if (
Value.isMinValue())
return Min;
12435 if (
Value.isMaxValue())
return Max;
12436 if (
Value >= PromotedMin)
return InRange;
12437 if (
Value <= PromotedMax)
return InRange;
12441 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12442 case -1:
return Less;
12443 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12445 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12446 case -1:
return InRange;
12447 case 0:
return Max;
12452 llvm_unreachable(
"impossible compare result");
12455 static std::optional<StringRef>
12457 if (Op == BO_Cmp) {
12459 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12461 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12462 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12463 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12464 return std::nullopt;
12471 }
else if (Op == BO_NE) {
12475 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12482 if (Op == BO_GE || Op == BO_LE)
12483 std::swap(TrueFlag, FalseFlag);
12486 return StringRef(
"true");
12488 return StringRef(
"false");
12489 return std::nullopt;
12496 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12497 if (ICE->getCastKind() != CK_IntegralCast &&
12498 ICE->getCastKind() != CK_NoOp)
12500 E = ICE->getSubExpr();
12509 enum ConstantValueKind {
12514 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12515 return BL->getValue() ? ConstantValueKind::LiteralTrue
12516 : ConstantValueKind::LiteralFalse;
12517 return ConstantValueKind::Miscellaneous;
12522 const llvm::APSInt &
Value,
12523 bool RhsConstant) {
12539 if (
Constant->getType()->isEnumeralType() &&
12545 if (!OtherValueRange)
12550 OtherT = AT->getValueType();
12551 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12555 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12561 bool OtherIsBooleanDespiteType =
12563 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12564 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12568 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12569 Value.isUnsigned());
12570 auto Cmp = OtherPromotedValueRange.compare(
Value);
12577 bool TautologicalTypeCompare =
false;
12579 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12580 Value.isUnsigned());
12581 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12584 TautologicalTypeCompare =
true;
12592 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12601 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12607 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12608 Other->getType()->isUnsignedIntegerOrEnumerationType())
12609 TautologicalTypeCompare =
true;
12614 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12615 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12619 llvm::raw_svector_ostream OS(PrettySourceValue);
12621 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12622 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12623 Constant->IgnoreParenImpCasts())) {
12624 OS << (BL->getValue() ?
"YES" :
"NO");
12629 if (!TautologicalTypeCompare) {
12631 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12637 if (IsObjCSignedCharBool) {
12639 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12640 << OS.str() << *
Result);
12647 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12651 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12652 : diag::warn_tautological_bool_compare)
12654 << OtherIsBooleanDespiteType << *
Result
12661 ? diag::warn_unsigned_enum_always_true_comparison
12662 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12663 : diag::warn_unsigned_always_true_comparison)
12664 : diag::warn_tautological_constant_compare;
12700 if (
T->isIntegralType(S.
Context)) {
12701 std::optional<llvm::APSInt> RHSValue =
12703 std::optional<llvm::APSInt> LHSValue =
12707 if (RHSValue && LHSValue)
12711 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12713 const bool RhsConstant = (
bool)RHSValue;
12714 Expr *Const = RhsConstant ? RHS : LHS;
12716 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12725 if (!
T->hasUnsignedIntegerRepresentation()) {
12739 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12741 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12747 Expr *signedOperand, *unsignedOperand;
12750 "unsigned comparison between two signed integer expressions?");
12751 signedOperand = LHS;
12752 unsignedOperand = RHS;
12754 signedOperand = RHS;
12755 unsignedOperand = LHS;
12761 std::optional<IntRange> signedRange =
12773 if (signedRange->NonNegative)
12785 if (!unsignedRange)
12790 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12792 if (unsignedRange->Width < comparisonWidth)
12797 S.
PDiag(diag::warn_mixed_sign_comparison)
12816 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12821 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12822 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12823 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12824 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12825 << BitfieldEnumDecl;
12832 Init->isValueDependent() ||
12833 Init->isTypeDependent())
12836 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12846 const PreferredTypeAttr *PTAttr =
nullptr;
12848 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12850 ED = PTAttr->getType()->getAsEnumDecl();
12858 bool SignedEnum = ED->getNumNegativeBits() > 0;
12865 unsigned DiagID = 0;
12866 if (SignedEnum && !SignedBitfield) {
12869 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12871 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12872 }
else if (SignedBitfield && !SignedEnum &&
12873 ED->getNumPositiveBits() == FieldWidth) {
12876 ? diag::warn_signed_bitfield_enum_conversion
12877 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12880 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12885 << SignedEnum << TypeRange;
12887 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12894 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12895 ED->getNumNegativeBits())
12896 : ED->getNumPositiveBits();
12899 if (BitsNeeded > FieldWidth) {
12903 ? diag::warn_bitfield_too_small_for_enum
12904 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12905 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12909 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12919 unsigned OriginalWidth =
Value.getBitWidth();
12925 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12926 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12933 if (!
Value.isSigned() ||
Value.isNegative())
12934 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12935 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12936 OriginalWidth =
Value.getSignificantBits();
12938 if (OriginalWidth <= FieldWidth)
12942 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12946 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12947 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12951 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12953 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12954 ? diag::warn_impcast_single_bit_bitield_precision_constant
12955 : diag::warn_impcast_bitfield_precision_constant)
12956 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12957 <<
Init->getSourceRange();
12994 bool PruneControlFlow =
false) {
13001 if (
T.hasAddressSpace())
13003 if (PruneControlFlow) {
13017 bool PruneControlFlow =
false) {
13024 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
13029 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
13030 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
13035 llvm::APFloat
Value(0.0);
13041 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
13046 diag::warn_impcast_float_integer, PruneWarnings);
13049 bool isExact =
false;
13052 T->hasUnsignedIntegerRepresentation());
13053 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
13054 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
13062 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
13063 precision = (precision * 59 + 195) / 196;
13064 Value.toString(PrettySourceValue, precision);
13068 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
13069 << PrettySourceValue);
13072 if (
Result == llvm::APFloat::opOK && isExact) {
13073 if (IsLiteral)
return;
13074 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
13080 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
13083 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
13084 : diag::warn_impcast_float_to_integer_out_of_range,
13087 unsigned DiagID = 0;
13090 DiagID = diag::warn_impcast_literal_float_to_integer;
13091 }
else if (IntegerValue == 0) {
13092 if (
Value.isZero()) {
13094 diag::warn_impcast_float_integer, PruneWarnings);
13097 DiagID = diag::warn_impcast_float_to_integer_zero;
13099 if (IntegerValue.isUnsigned()) {
13100 if (!IntegerValue.isMaxValue()) {
13102 diag::warn_impcast_float_integer, PruneWarnings);
13105 if (!IntegerValue.isMaxSignedValue() &&
13106 !IntegerValue.isMinSignedValue()) {
13108 diag::warn_impcast_float_integer, PruneWarnings);
13112 DiagID = diag::warn_impcast_float_to_integer;
13117 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
13119 IntegerValue.toString(PrettyTargetValue);
13121 if (PruneWarnings) {
13124 << E->
getType() <<
T.getUnqualifiedType()
13125 << PrettySourceValue << PrettyTargetValue
13129 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
13138 "Must be compound assignment operation");
13149 ->getComputationResultType()
13156 if (ResultBT->isInteger())
13158 E->
getExprLoc(), diag::warn_impcast_float_integer);
13160 if (!ResultBT->isFloatingPoint())
13169 diag::warn_impcast_float_result_precision);
13174 if (!Range.Width)
return "0";
13176 llvm::APSInt ValueInRange =
Value;
13177 ValueInRange.setIsSigned(!Range.NonNegative);
13178 ValueInRange = ValueInRange.trunc(Range.Width);
13179 return toString(ValueInRange, 10);
13189 const Type *Source =
13191 if (
Target->isDependentType())
13194 const auto *FloatCandidateBT =
13195 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13196 const Type *BoolCandidateType = ToBool ?
Target : Source;
13199 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13204 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13210 S, TheCall->
getArg(I - 1),
false));
13212 S, TheCall->
getArg(I + 1),
false));
13217 diag::warn_impcast_floating_point_to_bool);
13232 if (!IsGNUNullExpr && !HasNullPtrType)
13236 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
13237 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
13240 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13253 if (IsGNUNullExpr && Loc.
isMacroID()) {
13256 if (MacroName ==
"NULL")
13264 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13278 const char FirstLiteralCharacter =
13280 if (FirstLiteralCharacter ==
'0')
13286 if (CC.
isValid() &&
T->isCharType()) {
13287 const char FirstContextCharacter =
13289 if (FirstContextCharacter ==
'{')
13297 const auto *IL = dyn_cast<IntegerLiteral>(E);
13299 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13300 if (UO->getOpcode() == UO_Minus)
13301 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13312 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13316 if (Opc == BO_Shl) {
13319 if (LHS && LHS->getValue() == 0)
13320 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13322 RHS->getValue().isNonNegative() &&
13324 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13325 << (
Result.Val.getInt() != 0);
13327 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13334 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13339 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13340 (RHS->getValue() == 0 || RHS->getValue() == 1))
13343 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13344 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13352 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13358 if (Source->isChar16Type() &&
Target->isChar32Type())
13364 llvm::APSInt
Value(32);
13366 bool IsASCII =
Value <= 0x7F;
13367 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13368 bool ConversionPreservesSemantics =
13369 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13371 if (!ConversionPreservesSemantics) {
13372 auto IsSingleCodeUnitCP = [](
const QualType &
T,
13373 const llvm::APSInt &
Value) {
13374 if (
T->isChar8Type())
13375 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13376 if (
T->isChar16Type())
13377 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13378 assert(
T->isChar32Type());
13379 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13382 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13391 LosesPrecision ? diag::warn_impcast_unicode_precision
13392 : diag::warn_impcast_unicode_char_type);
13397 From =
Context.getCanonicalType(From);
13398 To =
Context.getCanonicalType(To);
13401 From = MaybePointee;
13408 if (FromFn->getCFIUncheckedCalleeAttr() &&
13409 !ToFn->getCFIUncheckedCalleeAttr())
13417 bool *ICContext,
bool IsListInit) {
13422 if (Source ==
Target)
return;
13423 if (
Target->isDependentType())
return;
13433 if (Source->isAtomicType())
13437 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13443 diag::warn_impcast_string_literal_to_bool);
13449 diag::warn_impcast_objective_c_literal_to_bool);
13451 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13463 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
13466 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13468 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13477 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13479 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13490 diag::err_impcast_incompatible_type);
13495 ? diag::err_impcast_complex_scalar
13496 : diag::warn_impcast_complex_scalar);
13505 if (
Target->isSveVLSBuiltinType() &&
13512 if (
Target->isRVVVLSBuiltinType() &&
13522 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
13530 diag::warn_hlsl_impcast_vector_truncation);
13542 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13543 Target = VecTy->getElementType().getTypePtr();
13547 if (
Target->isScalarType())
13548 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
13556 diag::warn_hlsl_impcast_matrix_truncation);
13562 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13563 Target = MatTy->getElementType().getTypePtr();
13565 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13571 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
13574 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13576 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13618 else if (Order < 0) {
13628 if (TargetBT && TargetBT->
isInteger()) {
13655 diag::warn_impcast_floating_point_to_bool);
13663 if (Source->isFixedPointType()) {
13664 if (
Target->isUnsaturatedFixedPointType()) {
13668 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13669 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13670 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13673 PDiag(diag::warn_impcast_fixed_point_range)
13674 <<
Value.toString() <<
T
13680 }
else if (
Target->isIntegerType()) {
13684 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13687 llvm::APSInt IntResult = FXResult.convertToInt(
13688 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13693 PDiag(diag::warn_impcast_fixed_point_range)
13694 << FXResult.toString() <<
T
13701 }
else if (
Target->isUnsaturatedFixedPointType()) {
13702 if (Source->isIntegerType()) {
13709 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13714 PDiag(diag::warn_impcast_fixed_point_range)
13735 unsigned int SourcePrecision =
SourceRange->Width;
13739 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13742 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13743 SourcePrecision > TargetPrecision) {
13745 if (std::optional<llvm::APSInt> SourceInt =
13750 llvm::APFloat TargetFloatValue(
13752 llvm::APFloat::opStatus ConversionStatus =
13753 TargetFloatValue.convertFromAPInt(
13755 llvm::APFloat::rmNearestTiesToEven);
13757 if (ConversionStatus != llvm::APFloat::opOK) {
13759 SourceInt->toString(PrettySourceValue, 10);
13761 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13765 PDiag(diag::warn_impcast_integer_float_precision_constant)
13766 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13772 diag::warn_impcast_integer_float_precision);
13781 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13786 if (
Target->isBooleanType())
13790 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13794 if (!Source->isIntegerType() || !
Target->isIntegerType())
13799 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13802 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13805 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13810 if (!LikelySourceRange)
13813 IntRange SourceTypeRange =
13814 IntRange::forTargetOfCanonicalType(
Context, Source);
13815 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13817 if (LikelySourceRange->Width > TargetRange.Width) {
13821 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13822 if (TargetOBT->isWrapKind()) {
13829 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13830 if (SourceOBT->isWrapKind()) {
13840 llvm::APSInt
Value(32);
13850 PDiag(diag::warn_impcast_integer_precision_constant)
13851 << PrettySourceValue << PrettyTargetValue
13861 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13862 if (UO->getOpcode() == UO_Minus)
13864 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13867 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13871 diag::warn_impcast_integer_precision);
13874 if (TargetRange.Width > SourceTypeRange.Width) {
13875 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13876 if (UO->getOpcode() == UO_Minus)
13877 if (Source->isUnsignedIntegerType()) {
13878 if (
Target->isUnsignedIntegerType())
13880 diag::warn_impcast_high_order_zero_bits);
13881 if (
Target->isSignedIntegerType())
13883 diag::warn_impcast_nonnegative_result);
13887 if (TargetRange.Width == LikelySourceRange->Width &&
13888 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13889 Source->isSignedIntegerType()) {
13903 PDiag(diag::warn_impcast_integer_precision_constant)
13904 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13914 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13915 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13916 LikelySourceRange->Width == TargetRange.Width))) {
13920 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13922 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13926 unsigned DiagID = diag::warn_impcast_integer_sign;
13934 DiagID = diag::warn_impcast_integer_sign_conditional;
13951 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13953 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13954 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13955 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13956 TargetEnum->getDecl()->hasNameForLinkage() &&
13957 SourceEnum != TargetEnum) {
13962 diag::warn_impcast_different_enum_types);
13976 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13989 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13990 TrueExpr = BCO->getCommon();
13992 bool Suspicious =
false;
13996 if (
T->isBooleanType())
14001 if (!Suspicious)
return;
14004 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
14011 Suspicious =
false;
14016 E->
getType(), CC, &Suspicious);
14033struct AnalyzeImplicitConversionsWorkItem {
14042 bool ExtraCheckForImplicitConversion,
14045 WorkList.push_back({E, CC,
false});
14047 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
14054 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
14056 Expr *OrigE = Item.E;
14075 Expr *SourceExpr = E;
14080 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
14081 if (
auto *Src = OVE->getSourceExpr())
14084 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
14085 if (UO->getOpcode() == UO_Not &&
14086 UO->getSubExpr()->isKnownToHaveBooleanValue())
14087 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
14091 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
14092 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
14093 BO->getLHS()->isKnownToHaveBooleanValue() &&
14094 BO->getRHS()->isKnownToHaveBooleanValue() &&
14095 BO->getLHS()->HasSideEffects(S.
Context) &&
14096 BO->getRHS()->HasSideEffects(S.
Context)) {
14107 if (SR.str() ==
"&" || SR.str() ==
"|") {
14109 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
14110 << (BO->getOpcode() == BO_And ?
"&" :
"|")
14113 BO->getOperatorLoc(),
14114 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
14115 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
14117 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
14135 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14141 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14156 for (
auto *SE : POE->semantics())
14157 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14158 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14162 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14163 E = CE->getSubExpr();
14169 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14170 if (InitListE->getNumInits() == 1) {
14171 E = InitListE->getInit(0);
14178 WorkList.push_back({E, CC, IsListInit});
14182 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14183 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14187 if (OutArgE->isInOut())
14188 WorkList.push_back(
14189 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14190 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14196 if (BO->isComparisonOp())
14200 if (BO->getOpcode() == BO_Assign)
14203 if (BO->isAssignmentOp())
14219 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14221 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14225 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14226 if (ChildExpr == CSE->getOperand())
14232 if (IsLogicalAndOperator &&
14237 WorkList.push_back({ChildExpr, CC, IsListInit});
14251 if (
U->getOpcode() == UO_LNot) {
14253 }
else if (
U->getOpcode() != UO_AddrOf) {
14254 if (
U->getSubExpr()->getType()->isAtomicType())
14255 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14256 diag::warn_atomic_implicit_seq_cst);
14267 WorkList.push_back({OrigE, CC, IsListInit});
14268 while (!WorkList.empty())
14280 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14283 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14284 if (!M->getMemberDecl()->getType()->isReferenceType())
14286 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14287 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14289 FD =
Call->getDirectCallee();
14298 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14338 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14339 : diag::warn_this_bool_conversion;
14344 bool IsAddressOf =
false;
14346 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14347 if (UO->getOpcode() != UO_AddrOf)
14349 IsAddressOf =
true;
14350 E = UO->getSubExpr();
14354 unsigned DiagID = IsCompare
14355 ? diag::warn_address_of_reference_null_compare
14356 : diag::warn_address_of_reference_bool_conversion;
14364 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14367 llvm::raw_string_ostream S(Str);
14369 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14370 : diag::warn_cast_nonnull_to_bool;
14373 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14378 if (
auto *Callee =
Call->getDirectCallee()) {
14379 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14380 ComplainAboutNonnullParamOrCall(A);
14389 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14390 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14391 MRecordDecl && MRecordDecl->isLambda()) {
14394 << MRecordDecl->getSourceRange() << Range << IsEqual;
14404 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14405 D = M->getMemberDecl();
14413 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14416 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14417 ComplainAboutNonnullParamOrCall(A);
14421 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14425 auto ParamIter = llvm::find(FD->
parameters(), PV);
14427 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14431 ComplainAboutNonnullParamOrCall(
NonNull);
14436 if (ArgNo.getASTIndex() == ParamNo) {
14437 ComplainAboutNonnullParamOrCall(
NonNull);
14448 const bool IsFunctionReference =
14449 T->isReferenceType() &&
T->getPointeeType()->isFunctionType();
14450 if (IsFunctionReference)
14451 T =
T->getPointeeType();
14452 const bool IsArray =
T->isArrayType();
14453 const bool IsFunction =
T->isFunctionType();
14456 if (IsAddressOf && IsFunction) {
14461 if (!IsAddressOf && !IsFunction && !IsArray)
14466 llvm::raw_string_ostream S(Str);
14469 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14470 : diag::warn_impcast_pointer_to_bool;
14477 DiagType = AddressOf;
14478 else if (IsFunction)
14479 DiagType = FunctionPointer;
14481 DiagType = ArrayPointer;
14483 llvm_unreachable(
"Could not determine diagnostic.");
14485 << Range << IsEqual;
14488 if (!IsFunction || IsFunctionReference)
14499 if (ReturnType.
isNull())
14530 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14531 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14533 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14534 Target->isUnsignedIntegerType()) {
14538 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14539 : diag::warn_impcast_overflow_behavior_pedantic;
14543 ? diag::warn_impcast_overflow_behavior_assignment
14544 : diag::warn_impcast_overflow_behavior;
14550 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14551 if (TargetOBT->isWrapKind()) {
14571 CheckArrayAccess(E);
14581void Sema::CheckForIntOverflow (
const Expr *E) {
14583 SmallVector<const Expr *, 2> Exprs(1, E);
14586 const Expr *OriginalE = Exprs.pop_back_val();
14595 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14596 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14599 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14600 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14601 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14603 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14604 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14605 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14606 Exprs.push_back(Temporary->getSubExpr());
14607 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14608 Exprs.push_back(
Array->getIdx());
14609 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14610 Exprs.push_back(Compound->getInitializer());
14611 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14612 New &&
New->isArray()) {
14613 if (
auto ArraySize =
New->getArraySize())
14614 Exprs.push_back(*ArraySize);
14615 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14616 Exprs.push_back(MTE->getSubExpr());
14617 }
while (!Exprs.empty());
14625 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14632 class SequenceTree {
14634 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14635 unsigned Parent : 31;
14636 LLVM_PREFERRED_TYPE(
bool)
14637 unsigned Merged : 1;
14639 SmallVector<Value, 8> Values;
14645 friend class SequenceTree;
14649 explicit Seq(
unsigned N) : Index(N) {}
14652 Seq() : Index(0) {}
14655 SequenceTree() { Values.push_back(
Value(0)); }
14656 Seq root()
const {
return Seq(0); }
14661 Seq allocate(
Seq Parent) {
14662 Values.push_back(
Value(Parent.Index));
14663 return Seq(Values.size() - 1);
14668 Values[S.Index].Merged =
true;
14674 bool isUnsequenced(
Seq Cur,
Seq Old) {
14675 unsigned C = representative(Cur.Index);
14676 unsigned Target = representative(Old.Index);
14680 C = Values[
C].Parent;
14687 unsigned representative(
unsigned K) {
14688 if (Values[K].Merged)
14690 return Values[K].Parent = representative(Values[K].Parent);
14696 using Object =
const NamedDecl *;
14710 UK_ModAsSideEffect,
14712 UK_Count = UK_ModAsSideEffect + 1
14718 const Expr *UsageExpr =
nullptr;
14719 SequenceTree::Seq
Seq;
14725 Usage Uses[UK_Count];
14728 bool Diagnosed =
false;
14732 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14740 UsageInfoMap UsageMap;
14743 SequenceTree::Seq Region;
14747 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14751 SmallVectorImpl<const Expr *> &WorkList;
14758 struct SequencedSubexpression {
14759 SequencedSubexpression(SequenceChecker &
Self)
14760 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14761 Self.ModAsSideEffect = &ModAsSideEffect;
14764 ~SequencedSubexpression() {
14765 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14769 UsageInfo &UI =
Self.UsageMap[M.first];
14770 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14771 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14772 SideEffectUsage = M.second;
14774 Self.ModAsSideEffect = OldModAsSideEffect;
14777 SequenceChecker &
Self;
14778 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14779 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14786 class EvaluationTracker {
14788 EvaluationTracker(SequenceChecker &
Self)
14790 Self.EvalTracker =
this;
14793 ~EvaluationTracker() {
14794 Self.EvalTracker = Prev;
14796 Prev->EvalOK &= EvalOK;
14799 bool evaluate(
const Expr *E,
bool &
Result) {
14804 Self.SemaRef.isConstantEvaluatedContext());
14809 SequenceChecker &
Self;
14810 EvaluationTracker *Prev;
14811 bool EvalOK =
true;
14812 } *EvalTracker =
nullptr;
14816 Object getObject(
const Expr *E,
bool Mod)
const {
14818 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14819 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14820 return getObject(UO->getSubExpr(), Mod);
14821 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14822 if (BO->getOpcode() == BO_Comma)
14823 return getObject(BO->getRHS(), Mod);
14824 if (Mod && BO->isAssignmentOp())
14825 return getObject(BO->getLHS(), Mod);
14826 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14829 return ME->getMemberDecl();
14830 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14839 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14841 Usage &U = UI.Uses[UK];
14842 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14846 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14847 ModAsSideEffect->push_back(std::make_pair(O, U));
14849 U.UsageExpr = UsageExpr;
14859 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14860 UsageKind OtherKind,
bool IsModMod) {
14864 const Usage &U = UI.Uses[OtherKind];
14865 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14868 const Expr *Mod = U.UsageExpr;
14869 const Expr *ModOrUse = UsageExpr;
14870 if (OtherKind == UK_Use)
14871 std::swap(Mod, ModOrUse);
14875 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14876 : diag::warn_unsequenced_mod_use)
14877 << O << SourceRange(ModOrUse->
getExprLoc()));
14878 UI.Diagnosed =
true;
14907 void notePreUse(
Object O,
const Expr *UseExpr) {
14908 UsageInfo &UI = UsageMap[O];
14910 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14913 void notePostUse(
Object O,
const Expr *UseExpr) {
14914 UsageInfo &UI = UsageMap[O];
14915 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14917 addUsage(O, UI, UseExpr, UK_Use);
14920 void notePreMod(
Object O,
const Expr *ModExpr) {
14921 UsageInfo &UI = UsageMap[O];
14923 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14924 checkUsage(O, UI, ModExpr, UK_Use,
false);
14927 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14928 UsageInfo &UI = UsageMap[O];
14929 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14931 addUsage(O, UI, ModExpr, UK);
14935 SequenceChecker(Sema &S,
const Expr *E,
14936 SmallVectorImpl<const Expr *> &WorkList)
14937 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14941 (void)this->WorkList;
14944 void VisitStmt(
const Stmt *S) {
14948 void VisitExpr(
const Expr *E) {
14950 Base::VisitStmt(E);
14953 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14954 for (
auto *Sub : CSE->
children()) {
14955 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14970 void VisitCastExpr(
const CastExpr *E) {
14982 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14983 const Expr *SequencedAfter) {
14984 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14985 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14986 SequenceTree::Seq OldRegion = Region;
14989 SequencedSubexpression SeqBefore(*
this);
14990 Region = BeforeRegion;
14991 Visit(SequencedBefore);
14994 Region = AfterRegion;
14995 Visit(SequencedAfter);
14997 Region = OldRegion;
14999 Tree.merge(BeforeRegion);
15000 Tree.merge(AfterRegion);
15003 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
15008 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
15015 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15016 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15017 void VisitBinPtrMem(
const BinaryOperator *BO) {
15022 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15029 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15030 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15031 void VisitBinShlShr(
const BinaryOperator *BO) {
15035 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15042 void VisitBinComma(
const BinaryOperator *BO) {
15047 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15050 void VisitBinAssign(
const BinaryOperator *BO) {
15051 SequenceTree::Seq RHSRegion;
15052 SequenceTree::Seq LHSRegion;
15054 RHSRegion = Tree.allocate(Region);
15055 LHSRegion = Tree.allocate(Region);
15057 RHSRegion = Region;
15058 LHSRegion = Region;
15060 SequenceTree::Seq OldRegion = Region;
15076 SequencedSubexpression SeqBefore(*
this);
15077 Region = RHSRegion;
15081 Region = LHSRegion;
15085 notePostUse(O, BO);
15089 Region = LHSRegion;
15093 notePostUse(O, BO);
15095 Region = RHSRegion;
15103 Region = OldRegion;
15107 : UK_ModAsSideEffect);
15109 Tree.merge(RHSRegion);
15110 Tree.merge(LHSRegion);
15114 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
15115 VisitBinAssign(CAO);
15118 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15119 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15120 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
15123 return VisitExpr(UO);
15131 : UK_ModAsSideEffect);
15134 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15135 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15136 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15139 return VisitExpr(UO);
15143 notePostMod(O, UO, UK_ModAsSideEffect);
15146 void VisitBinLOr(
const BinaryOperator *BO) {
15152 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15153 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15154 SequenceTree::Seq OldRegion = Region;
15156 EvaluationTracker Eval(*
this);
15158 SequencedSubexpression Sequenced(*
this);
15159 Region = LHSRegion;
15166 bool EvalResult =
false;
15167 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15168 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15169 if (ShouldVisitRHS) {
15170 Region = RHSRegion;
15174 Region = OldRegion;
15175 Tree.merge(LHSRegion);
15176 Tree.merge(RHSRegion);
15179 void VisitBinLAnd(
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;
15198 bool EvalResult =
false;
15199 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15200 bool ShouldVisitRHS = !EvalOK || EvalResult;
15201 if (ShouldVisitRHS) {
15202 Region = RHSRegion;
15206 Region = OldRegion;
15207 Tree.merge(LHSRegion);
15208 Tree.merge(RHSRegion);
15211 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15216 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15232 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15233 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15234 SequenceTree::Seq OldRegion = Region;
15236 EvaluationTracker Eval(*
this);
15238 SequencedSubexpression Sequenced(*
this);
15239 Region = ConditionRegion;
15249 bool EvalResult =
false;
15250 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15251 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15252 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15253 if (ShouldVisitTrueExpr) {
15254 Region = TrueRegion;
15257 if (ShouldVisitFalseExpr) {
15258 Region = FalseRegion;
15262 Region = OldRegion;
15263 Tree.merge(ConditionRegion);
15264 Tree.merge(TrueRegion);
15265 Tree.merge(FalseRegion);
15268 void VisitCallExpr(
const CallExpr *CE) {
15280 SequencedSubexpression Sequenced(*
this);
15285 SequenceTree::Seq CalleeRegion;
15286 SequenceTree::Seq OtherRegion;
15287 if (SemaRef.getLangOpts().CPlusPlus17) {
15288 CalleeRegion = Tree.allocate(Region);
15289 OtherRegion = Tree.allocate(Region);
15291 CalleeRegion = Region;
15292 OtherRegion = Region;
15294 SequenceTree::Seq OldRegion = Region;
15297 Region = CalleeRegion;
15299 SequencedSubexpression Sequenced(*this);
15300 Visit(CE->getCallee());
15302 Visit(CE->getCallee());
15306 Region = OtherRegion;
15310 Region = OldRegion;
15312 Tree.merge(CalleeRegion);
15313 Tree.merge(OtherRegion);
15331 return VisitCallExpr(CXXOCE);
15342 case OO_MinusEqual:
15344 case OO_SlashEqual:
15345 case OO_PercentEqual:
15346 case OO_CaretEqual:
15349 case OO_LessLessEqual:
15350 case OO_GreaterGreaterEqual:
15351 SequencingKind = RHSBeforeLHS;
15355 case OO_GreaterGreater:
15361 SequencingKind = LHSBeforeRHS;
15365 SequencingKind = LHSBeforeRest;
15369 SequencingKind = NoSequencing;
15373 if (SequencingKind == NoSequencing)
15374 return VisitCallExpr(CXXOCE);
15377 SequencedSubexpression Sequenced(*
this);
15380 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15381 "Should only get there with C++17 and above!");
15382 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15383 "Should only get there with an overloaded binary operator"
15384 " or an overloaded call operator!");
15386 if (SequencingKind == LHSBeforeRest) {
15387 assert(CXXOCE->getOperator() == OO_Call &&
15388 "We should only have an overloaded call operator here!");
15397 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15398 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15399 SequenceTree::Seq OldRegion = Region;
15401 assert(CXXOCE->getNumArgs() >= 1 &&
15402 "An overloaded call operator must have at least one argument"
15403 " for the postfix-expression!");
15404 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15405 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15406 CXXOCE->getNumArgs() - 1);
15410 Region = PostfixExprRegion;
15411 SequencedSubexpression Sequenced(*this);
15412 Visit(PostfixExpr);
15416 Region = ArgsRegion;
15417 for (const Expr *Arg : Args)
15420 Region = OldRegion;
15421 Tree.merge(PostfixExprRegion);
15422 Tree.merge(ArgsRegion);
15424 assert(CXXOCE->getNumArgs() == 2 &&
15425 "Should only have two arguments here!");
15426 assert((SequencingKind == LHSBeforeRHS ||
15427 SequencingKind == RHSBeforeLHS) &&
15428 "Unexpected sequencing kind!");
15432 const Expr *E1 = CXXOCE->getArg(0);
15433 const Expr *E2 = CXXOCE->getArg(1);
15434 if (SequencingKind == RHSBeforeLHS)
15437 return VisitSequencedExpressions(E1, E2);
15444 SequencedSubexpression Sequenced(*
this);
15447 return VisitExpr(CCE);
15450 SequenceExpressionsInOrder(
15456 return VisitExpr(ILE);
15459 SequenceExpressionsInOrder(ILE->
inits());
15471 SequenceTree::Seq Parent = Region;
15472 for (
const Expr *E : ExpressionList) {
15475 Region = Tree.allocate(Parent);
15476 Elts.push_back(Region);
15482 for (
unsigned I = 0; I < Elts.size(); ++I)
15483 Tree.merge(Elts[I]);
15487SequenceChecker::UsageInfo::UsageInfo() =
default;
15491void Sema::CheckUnsequencedOperations(
const Expr *E) {
15492 SmallVector<const Expr *, 8> WorkList;
15493 WorkList.push_back(E);
15494 while (!WorkList.empty()) {
15495 const Expr *Item = WorkList.pop_back_val();
15496 SequenceChecker(*
this, Item, WorkList);
15501 bool IsConstexpr) {
15504 CheckImplicitConversions(E, CheckLoc);
15506 CheckUnsequencedOperations(E);
15508 CheckForIntOverflow(E);
15521 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15525 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15529 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15543 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15547 bool CheckParameterNames) {
15548 bool HasInvalidParm =
false;
15550 assert(Param &&
"null in a parameter list");
15559 if (!Param->isInvalidDecl() &&
15561 diag::err_typecheck_decl_incomplete_type) ||
15563 diag::err_abstract_type_in_decl,
15565 Param->setInvalidDecl();
15566 HasInvalidParm =
true;
15571 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15575 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15583 QualType PType = Param->getOriginalType();
15591 if (!Param->isInvalidDecl()) {
15592 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15593 if (!ClassDecl->isInvalidDecl() &&
15594 !ClassDecl->hasIrrelevantDestructor() &&
15595 !ClassDecl->isDependentContext() &&
15596 ClassDecl->isParamDestroyedInCallee()) {
15608 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15609 if (!Param->getType().isConstQualified())
15610 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15614 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15619 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15620 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15625 if (!Param->isInvalidDecl() &&
15626 Param->getOriginalType()->isWebAssemblyTableType()) {
15627 Param->setInvalidDecl();
15628 HasInvalidParm =
true;
15629 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15633 return HasInvalidParm;
15636std::optional<std::pair<
15645static std::pair<CharUnits, CharUnits>
15653 if (
Base->isVirtual()) {
15660 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15667 DerivedType =
Base->getType();
15670 return std::make_pair(BaseAlignment, Offset);
15674static std::optional<std::pair<CharUnits, CharUnits>>
15680 return std::nullopt;
15685 return std::nullopt;
15689 CharUnits Offset = EltSize * IdxRes->getExtValue();
15692 return std::make_pair(P->first, P->second + Offset);
15698 return std::make_pair(
15699 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15705std::optional<std::pair<
15713 case Stmt::CStyleCastExprClass:
15714 case Stmt::CXXStaticCastExprClass:
15715 case Stmt::ImplicitCastExprClass: {
15717 const Expr *From = CE->getSubExpr();
15718 switch (CE->getCastKind()) {
15723 case CK_UncheckedDerivedToBase:
15724 case CK_DerivedToBase: {
15734 case Stmt::ArraySubscriptExprClass: {
15739 case Stmt::DeclRefExprClass: {
15743 if (!VD->getType()->isReferenceType()) {
15745 if (VD->hasDependentAlignment())
15754 case Stmt::MemberExprClass: {
15756 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15760 std::optional<std::pair<CharUnits, CharUnits>> P;
15769 return std::make_pair(P->first,
15772 case Stmt::UnaryOperatorClass: {
15782 case Stmt::BinaryOperatorClass: {
15794 return std::nullopt;
15799std::optional<std::pair<
15808 case Stmt::CStyleCastExprClass:
15809 case Stmt::CXXStaticCastExprClass:
15810 case Stmt::ImplicitCastExprClass: {
15812 const Expr *From = CE->getSubExpr();
15813 switch (CE->getCastKind()) {
15818 case CK_ArrayToPointerDecay:
15820 case CK_UncheckedDerivedToBase:
15821 case CK_DerivedToBase: {
15831 case Stmt::CXXThisExprClass: {
15836 case Stmt::UnaryOperatorClass: {
15842 case Stmt::BinaryOperatorClass: {
15851 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15852 std::swap(LHS, RHS);
15862 return std::nullopt;
15867 std::optional<std::pair<CharUnits, CharUnits>> P =
15871 return P->first.alignmentAtOffset(P->second);
15889 if (!DestPtr)
return;
15895 if (DestAlign.
isOne())
return;
15899 if (!SrcPtr)
return;
15910 if (SrcAlign >= DestAlign)
return;
15915 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15919void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15921 bool AllowOnePastEnd,
bool IndexNegated) {
15930 const Type *EffectiveType =
15934 Context.getAsConstantArrayType(BaseExpr->
getType());
15937 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15939 const Type *BaseType =
15941 bool IsUnboundedArray =
15943 Context, StrictFlexArraysLevel,
15946 (!IsUnboundedArray && BaseType->isDependentType()))
15954 if (IndexNegated) {
15955 index.setIsUnsigned(
false);
15959 if (IsUnboundedArray) {
15962 if (
index.isUnsigned() || !
index.isNegative()) {
15964 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15966 if (
index.getBitWidth() < AddrBits)
15968 std::optional<CharUnits> ElemCharUnits =
15969 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15972 if (!ElemCharUnits || ElemCharUnits->isZero())
15974 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15979 if (
index.getActiveBits() <= AddrBits) {
15981 llvm::APInt Product(
index);
15983 Product = Product.umul_ov(ElemBytes, Overflow);
15984 if (!Overflow && Product.getActiveBits() <= AddrBits)
15990 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15991 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15993 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15994 MaxElems = MaxElems.udiv(ElemBytes);
15997 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15998 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
16003 PDiag(DiagID) << index << AddrBits
16004 << (
unsigned)ASTC.toBits(*ElemCharUnits)
16005 << ElemBytes << MaxElems
16006 << MaxElems.getZExtValue()
16009 const NamedDecl *ND =
nullptr;
16011 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16013 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16015 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16016 ND = ME->getMemberDecl();
16020 PDiag(diag::note_array_declared_here) << ND);
16025 if (index.isUnsigned() || !index.isNegative()) {
16035 llvm::APInt size = ArrayTy->
getSize();
16037 if (BaseType != EffectiveType) {
16045 if (!ptrarith_typesize)
16046 ptrarith_typesize =
Context.getCharWidth();
16048 if (ptrarith_typesize != array_typesize) {
16050 uint64_t ratio = array_typesize / ptrarith_typesize;
16054 if (ptrarith_typesize * ratio == array_typesize)
16055 size *= llvm::APInt(size.getBitWidth(), ratio);
16059 if (size.getBitWidth() > index.getBitWidth())
16060 index = index.zext(size.getBitWidth());
16061 else if (size.getBitWidth() < index.getBitWidth())
16062 size = size.zext(index.getBitWidth());
16068 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
16075 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
16077 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
16078 SourceLocation IndexLoc =
16080 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
16085 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
16086 : diag::warn_ptr_arith_exceeds_bounds;
16087 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
16088 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
16092 << index << ArrayTy->
desugar() << CastMsg
16095 unsigned DiagID = diag::warn_array_index_precedes_bounds;
16097 DiagID = diag::warn_ptr_arith_precedes_bounds;
16098 if (index.isNegative()) index = -index;
16105 const NamedDecl *ND =
nullptr;
16107 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16109 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16111 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16112 ND = ME->getMemberDecl();
16116 PDiag(diag::note_array_declared_here) << ND);
16119void Sema::CheckArrayAccess(
const Expr *
expr) {
16120 int AllowOnePastEnd = 0;
16122 expr =
expr->IgnoreParenImpCasts();
16123 switch (
expr->getStmtClass()) {
16124 case Stmt::ArraySubscriptExprClass: {
16127 AllowOnePastEnd > 0);
16131 case Stmt::MemberExprClass: {
16135 case Stmt::CXXMemberCallExprClass: {
16139 case Stmt::ArraySectionExprClass: {
16145 nullptr, AllowOnePastEnd > 0);
16148 case Stmt::UnaryOperatorClass: {
16164 case Stmt::ConditionalOperatorClass: {
16166 if (
const Expr *lhs = cond->
getLHS())
16167 CheckArrayAccess(lhs);
16168 if (
const Expr *rhs = cond->
getRHS())
16169 CheckArrayAccess(rhs);
16172 case Stmt::CXXOperatorCallExprClass: {
16174 for (
const auto *Arg : OCE->arguments())
16175 CheckArrayAccess(Arg);
16185 Expr *RHS,
bool isProperty) {
16197 S.
Diag(Loc, diag::warn_arc_literal_assign)
16199 << (isProperty ? 0 : 1)
16207 Expr *RHS,
bool isProperty) {
16210 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16211 S.
Diag(Loc, diag::warn_arc_retained_assign)
16213 << (isProperty ? 0 : 1)
16217 RHS =
cast->getSubExpr();
16259 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16288 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16289 Diag(Loc, diag::warn_arc_retained_property_assign)
16293 RHS =
cast->getSubExpr();
16316 bool StmtLineInvalid;
16317 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16319 if (StmtLineInvalid)
16322 bool BodyLineInvalid;
16323 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16325 if (BodyLineInvalid)
16329 if (StmtLine != BodyLine)
16344 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16353 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16357 const Stmt *PossibleBody) {
16363 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16364 StmtLoc = FS->getRParenLoc();
16365 Body = FS->getBody();
16366 DiagID = diag::warn_empty_for_body;
16367 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16368 StmtLoc = WS->getRParenLoc();
16369 Body = WS->getBody();
16370 DiagID = diag::warn_empty_while_body;
16375 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16399 if (!ProbableTypo) {
16400 bool BodyColInvalid;
16401 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16403 if (BodyColInvalid)
16406 bool StmtColInvalid;
16409 if (StmtColInvalid)
16412 if (BodyCol > StmtCol)
16413 ProbableTypo =
true;
16416 if (ProbableTypo) {
16418 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16426 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16438 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16440 RHSExpr = CE->
getArg(0);
16441 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16442 CXXSCE && CXXSCE->isXValue())
16443 RHSExpr = CXXSCE->getSubExpr();
16447 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16448 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16451 if (LHSDeclRef && RHSDeclRef) {
16458 auto D =
Diag(OpLoc, diag::warn_self_move)
16474 const Expr *LHSBase = LHSExpr;
16475 const Expr *RHSBase = RHSExpr;
16476 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16477 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16478 if (!LHSME || !RHSME)
16481 while (LHSME && RHSME) {
16488 LHSME = dyn_cast<MemberExpr>(LHSBase);
16489 RHSME = dyn_cast<MemberExpr>(RHSBase);
16492 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16493 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16494 if (LHSDeclRef && RHSDeclRef) {
16501 Diag(OpLoc, diag::warn_self_move)
16508 Diag(OpLoc, diag::warn_self_move)
16532 bool AreUnionMembers =
false) {
16536 assert(((Field1Parent->isStructureOrClassType() &&
16537 Field2Parent->isStructureOrClassType()) ||
16538 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16539 "Can't evaluate layout compatibility between a struct field and a "
16541 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16542 (AreUnionMembers && Field1Parent->isUnionType())) &&
16543 "AreUnionMembers should be 'true' for union fields (only).");
16557 if (Bits1 != Bits2)
16561 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16562 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16565 if (!AreUnionMembers &&
16577 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16578 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16580 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16581 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16586 return isLayoutCompatible(C, F1, F2);
16597 for (
auto *Field1 : RD1->
fields()) {
16598 auto It = llvm::find_if(UnmatchedFields, [&](
const FieldDecl *Field2) {
16601 if (It == UnmatchedFields.end())
16603 [[maybe_unused]]
bool Result = UnmatchedFields.erase(*It);
16607 return UnmatchedFields.empty();
16633 if (
C.hasSameType(T1, T2))
16642 if (TC1 == Type::Enum)
16644 if (TC1 == Type::Record) {
16663 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16694 const ValueDecl **VD, uint64_t *MagicValue,
16695 bool isConstantEvaluated) {
16703 case Stmt::UnaryOperatorClass: {
16712 case Stmt::DeclRefExprClass: {
16718 case Stmt::IntegerLiteralClass: {
16720 llvm::APInt MagicValueAPInt = IL->
getValue();
16721 if (MagicValueAPInt.getActiveBits() <= 64) {
16722 *MagicValue = MagicValueAPInt.getZExtValue();
16728 case Stmt::BinaryConditionalOperatorClass:
16729 case Stmt::ConditionalOperatorClass: {
16734 isConstantEvaluated)) {
16744 case Stmt::BinaryOperatorClass: {
16747 TypeExpr = BO->
getRHS();
16777 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16780 bool isConstantEvaluated) {
16781 FoundWrongKind =
false;
16786 uint64_t MagicValue;
16788 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16792 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16793 if (I->getArgumentKind() != ArgumentKind) {
16794 FoundWrongKind =
true;
16797 TypeInfo.Type = I->getMatchingCType();
16798 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16799 TypeInfo.MustBeNull = I->getMustBeNull();
16810 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16811 if (I == MagicValues->end())
16820 bool LayoutCompatible,
16822 if (!TypeTagForDatatypeMagicValues)
16823 TypeTagForDatatypeMagicValues.reset(
16824 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16827 (*TypeTagForDatatypeMagicValues)[Magic] =
16843 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16844 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16845 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16846 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16849void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16852 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16853 bool IsPointerAttr = Attr->getIsPointer();
16856 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16857 if (TypeTagIdxAST >= ExprArgs.size()) {
16858 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16859 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16862 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16863 bool FoundWrongKind;
16866 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16868 if (FoundWrongKind)
16870 diag::warn_type_tag_for_datatype_wrong_kind)
16876 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16877 if (ArgumentIdxAST >= ExprArgs.size()) {
16878 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16879 << 1 << Attr->getArgumentIdx().getSourceIndex();
16882 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16883 if (IsPointerAttr) {
16885 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16886 if (ICE->getType()->isVoidPointerType() &&
16887 ICE->getCastKind() == CK_BitCast)
16888 ArgumentExpr = ICE->getSubExpr();
16890 QualType ArgumentType = ArgumentExpr->
getType();
16896 if (TypeInfo.MustBeNull) {
16901 diag::warn_type_safety_null_pointer_required)
16909 QualType RequiredType = TypeInfo.Type;
16911 RequiredType =
Context.getPointerType(RequiredType);
16913 bool mismatch =
false;
16914 if (!TypeInfo.LayoutCompatible) {
16915 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16936 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16937 << ArgumentType << ArgumentKind
16938 << TypeInfo.LayoutCompatible << RequiredType
16956 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16964 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16970 auto &MisalignedMembersForExpr =
16972 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16973 if (MA != MisalignedMembersForExpr.end() &&
16974 (
T->isDependentType() ||
T->isIntegerType() ||
16975 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16977 T->getPointeeType()) <= MA->Alignment))))
16978 MisalignedMembersForExpr.erase(MA);
16987 const auto *ME = dyn_cast<MemberExpr>(E);
16999 bool AnyIsPacked =
false;
17001 QualType BaseType = ME->getBase()->getType();
17002 if (BaseType->isDependentType())
17006 auto *RD = BaseType->castAsRecordDecl();
17011 auto *FD = dyn_cast<FieldDecl>(MD);
17017 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
17018 ReverseMemberChain.push_back(FD);
17021 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
17023 assert(TopME &&
"We did not compute a topmost MemberExpr!");
17030 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
17041 if (ExpectedAlignment.
isOne())
17046 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
17047 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
17051 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
17055 if (DRE && !TopME->
isArrow()) {
17058 CompleteObjectAlignment =
17059 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
17063 if (!Offset.isMultipleOf(ExpectedAlignment) ||
17066 CompleteObjectAlignment < ExpectedAlignment) {
17077 for (
FieldDecl *FDI : ReverseMemberChain) {
17078 if (FDI->hasAttr<PackedAttr>() ||
17079 FDI->getParent()->hasAttr<PackedAttr>()) {
17081 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
17087 assert(FD &&
"We did not find a packed FieldDecl!");
17088 Action(E, FD->
getParent(), FD, Alignment);
17092void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
17093 using namespace std::placeholders;
17096 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
17120bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
17121 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17148 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17165 assert(!Args.empty() &&
"Should have at least one argument.");
17167 Expr *Arg0 = Args.front();
17170 auto EmitError = [&](
Expr *ArgI) {
17172 diag::err_typecheck_call_different_arg_types)
17173 << Arg0->
getType() << ArgI->getType();
17178 for (
Expr *ArgI : Args.drop_front())
17189 for (
Expr *ArgI : Args.drop_front()) {
17190 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17193 VecI->getElementType()) ||
17194 Vec0->getNumElements() != VecI->getNumElements()) {
17203std::optional<QualType>
17207 return std::nullopt;
17211 return std::nullopt;
17214 for (
int I = 0; I < 2; ++I) {
17218 return std::nullopt;
17219 Args[I] = Converted.
get();
17226 return std::nullopt;
17229 return std::nullopt;
17231 TheCall->
setArg(0, Args[0]);
17232 TheCall->
setArg(1, Args[1]);
17243 TheCall->
getArg(1), Loc) ||
17245 TheCall->
getArg(2), Loc))
17249 for (
int I = 0; I < 3; ++I) {
17254 Args[I] = Converted.
get();
17257 int ArgOrdinal = 1;
17258 for (
Expr *Arg : Args) {
17260 ArgTyRestr, ArgOrdinal++))
17267 for (
int I = 0; I < 3; ++I)
17268 TheCall->
setArg(I, Args[I]);
17274bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17286bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17295 diag::err_builtin_invalid_arg_type)
17296 << 1 << 2 << 1 << 1 << TyArg;
17310 Expr *Matrix = MatrixArg.
get();
17312 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17315 << 1 << 3 << 0 << 0
17322 QualType ResultType =
Context.getConstantMatrixType(
17323 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17326 TheCall->
setType(ResultType);
17329 TheCall->
setArg(0, Matrix);
17334static std::optional<unsigned>
17342 uint64_t
Dim =
Value->getZExtValue();
17358 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17360 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17368 unsigned PtrArgIdx = 0;
17369 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17370 Expr *RowsExpr = TheCall->
getArg(1);
17371 Expr *ColumnsExpr = TheCall->
getArg(2);
17372 Expr *StrideExpr = TheCall->
getArg(3);
17374 bool ArgError =
false;
17381 PtrExpr = PtrConv.
get();
17382 TheCall->
setArg(0, PtrExpr);
17389 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17390 QualType ElementTy;
17393 << PtrArgIdx + 1 << 0 << 5 << 0
17397 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17401 << PtrArgIdx + 1 << 0 << 5
17408 auto ApplyArgumentConversions = [
this](Expr *E) {
17417 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17419 RowsExpr = RowsConv.
get();
17420 TheCall->
setArg(1, RowsExpr);
17422 RowsExpr =
nullptr;
17424 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17426 ColumnsExpr = ColumnsConv.
get();
17427 TheCall->
setArg(2, ColumnsExpr);
17429 ColumnsExpr =
nullptr;
17440 std::optional<unsigned> MaybeRows;
17444 std::optional<unsigned> MaybeColumns;
17449 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17452 StrideExpr = StrideConv.
get();
17453 TheCall->
setArg(3, StrideExpr);
17456 if (std::optional<llvm::APSInt>
Value =
17459 if (Stride < *MaybeRows) {
17461 diag::err_builtin_matrix_stride_too_small);
17467 if (ArgError || !MaybeRows || !MaybeColumns)
17471 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17482 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17484 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17492 unsigned PtrArgIdx = 1;
17493 Expr *MatrixExpr = TheCall->
getArg(0);
17494 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17495 Expr *StrideExpr = TheCall->
getArg(2);
17497 bool ArgError =
false;
17503 MatrixExpr = MatrixConv.
get();
17504 TheCall->
setArg(0, MatrixExpr);
17511 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17514 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17522 PtrExpr = PtrConv.
get();
17523 TheCall->
setArg(1, PtrExpr);
17531 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17534 << PtrArgIdx + 1 << 0 << 5 << 0
17538 QualType ElementTy = PtrTy->getPointeeType();
17540 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17545 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17547 diag::err_builtin_matrix_pointer_arg_mismatch)
17548 << ElementTy << MatrixTy->getElementType();
17563 StrideExpr = StrideConv.
get();
17564 TheCall->
setArg(2, StrideExpr);
17569 if (std::optional<llvm::APSInt>
Value =
17572 if (Stride < MatrixTy->getNumRows()) {
17574 diag::err_builtin_matrix_stride_too_small);
17594 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17599 llvm::StringSet<> CalleeTCBs;
17600 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17601 CalleeTCBs.insert(A->getTCBName());
17602 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17603 CalleeTCBs.insert(A->getTCBName());
17607 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17608 StringRef CallerTCB = A->getTCBName();
17609 if (CalleeTCBs.count(CallerTCB) == 0) {
17610 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17611 << 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 bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call)
static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall, QualType ReturnType)
Checks the __builtin_stdc_* builtins that take a single unsigned integer argument and return either i...
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis for SYCL constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
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
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 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 hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool 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.