16585 lines · cpp
1//===- SemaChecking.cpp - Extra Semantic Checking -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements extra semantic analysis beyond what is enforced10// by the C type system.11//12//===----------------------------------------------------------------------===//13 14#include "CheckExprLifetime.h"15#include "clang/AST/APValue.h"16#include "clang/AST/ASTContext.h"17#include "clang/AST/ASTDiagnostic.h"18#include "clang/AST/Attr.h"19#include "clang/AST/AttrIterator.h"20#include "clang/AST/CharUnits.h"21#include "clang/AST/Decl.h"22#include "clang/AST/DeclBase.h"23#include "clang/AST/DeclCXX.h"24#include "clang/AST/DeclObjC.h"25#include "clang/AST/DeclarationName.h"26#include "clang/AST/EvaluatedExprVisitor.h"27#include "clang/AST/Expr.h"28#include "clang/AST/ExprCXX.h"29#include "clang/AST/ExprObjC.h"30#include "clang/AST/FormatString.h"31#include "clang/AST/IgnoreExpr.h"32#include "clang/AST/NSAPI.h"33#include "clang/AST/NonTrivialTypeVisitor.h"34#include "clang/AST/OperationKinds.h"35#include "clang/AST/RecordLayout.h"36#include "clang/AST/Stmt.h"37#include "clang/AST/TemplateBase.h"38#include "clang/AST/TemplateName.h"39#include "clang/AST/Type.h"40#include "clang/AST/TypeLoc.h"41#include "clang/AST/UnresolvedSet.h"42#include "clang/Basic/AddressSpaces.h"43#include "clang/Basic/Diagnostic.h"44#include "clang/Basic/DiagnosticSema.h"45#include "clang/Basic/IdentifierTable.h"46#include "clang/Basic/LLVM.h"47#include "clang/Basic/LangOptions.h"48#include "clang/Basic/OpenCLOptions.h"49#include "clang/Basic/OperatorKinds.h"50#include "clang/Basic/PartialDiagnostic.h"51#include "clang/Basic/SourceLocation.h"52#include "clang/Basic/SourceManager.h"53#include "clang/Basic/Specifiers.h"54#include "clang/Basic/SyncScope.h"55#include "clang/Basic/TargetInfo.h"56#include "clang/Basic/TypeTraits.h"57#include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering.58#include "clang/Sema/Initialization.h"59#include "clang/Sema/Lookup.h"60#include "clang/Sema/Ownership.h"61#include "clang/Sema/Scope.h"62#include "clang/Sema/ScopeInfo.h"63#include "clang/Sema/Sema.h"64#include "clang/Sema/SemaAMDGPU.h"65#include "clang/Sema/SemaARM.h"66#include "clang/Sema/SemaBPF.h"67#include "clang/Sema/SemaDirectX.h"68#include "clang/Sema/SemaHLSL.h"69#include "clang/Sema/SemaHexagon.h"70#include "clang/Sema/SemaLoongArch.h"71#include "clang/Sema/SemaMIPS.h"72#include "clang/Sema/SemaNVPTX.h"73#include "clang/Sema/SemaObjC.h"74#include "clang/Sema/SemaOpenCL.h"75#include "clang/Sema/SemaPPC.h"76#include "clang/Sema/SemaRISCV.h"77#include "clang/Sema/SemaSPIRV.h"78#include "clang/Sema/SemaSystemZ.h"79#include "clang/Sema/SemaWasm.h"80#include "clang/Sema/SemaX86.h"81#include "llvm/ADT/APFloat.h"82#include "llvm/ADT/APInt.h"83#include "llvm/ADT/APSInt.h"84#include "llvm/ADT/ArrayRef.h"85#include "llvm/ADT/DenseMap.h"86#include "llvm/ADT/FoldingSet.h"87#include "llvm/ADT/STLExtras.h"88#include "llvm/ADT/STLForwardCompat.h"89#include "llvm/ADT/SmallBitVector.h"90#include "llvm/ADT/SmallPtrSet.h"91#include "llvm/ADT/SmallString.h"92#include "llvm/ADT/SmallVector.h"93#include "llvm/ADT/StringExtras.h"94#include "llvm/ADT/StringRef.h"95#include "llvm/ADT/StringSet.h"96#include "llvm/ADT/StringSwitch.h"97#include "llvm/Support/AtomicOrdering.h"98#include "llvm/Support/Compiler.h"99#include "llvm/Support/ConvertUTF.h"100#include "llvm/Support/ErrorHandling.h"101#include "llvm/Support/Format.h"102#include "llvm/Support/Locale.h"103#include "llvm/Support/MathExtras.h"104#include "llvm/Support/SaveAndRestore.h"105#include "llvm/Support/raw_ostream.h"106#include "llvm/TargetParser/RISCVTargetParser.h"107#include "llvm/TargetParser/Triple.h"108#include <algorithm>109#include <cassert>110#include <cctype>111#include <cstddef>112#include <cstdint>113#include <functional>114#include <limits>115#include <optional>116#include <string>117#include <tuple>118#include <utility>119 120using namespace clang;121using namespace sema;122 123SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,124 unsigned ByteNo) const {125 return SL->getLocationOfByte(ByteNo, getSourceManager(), LangOpts,126 Context.getTargetInfo());127}128 129static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A,130 Sema::FormatArgumentPassingKind B) {131 return (A << 8) | B;132}133 134bool Sema::checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount) {135 unsigned ArgCount = Call->getNumArgs();136 if (ArgCount >= MinArgCount)137 return false;138 139 return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args)140 << 0 /*function call*/ << MinArgCount << ArgCount141 << /*is non object*/ 0 << Call->getSourceRange();142}143 144bool Sema::checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount) {145 unsigned ArgCount = Call->getNumArgs();146 if (ArgCount <= MaxArgCount)147 return false;148 return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)149 << 0 /*function call*/ << MaxArgCount << ArgCount150 << /*is non object*/ 0 << Call->getSourceRange();151}152 153bool Sema::checkArgCountRange(CallExpr *Call, unsigned MinArgCount,154 unsigned MaxArgCount) {155 return checkArgCountAtLeast(Call, MinArgCount) ||156 checkArgCountAtMost(Call, MaxArgCount);157}158 159bool Sema::checkArgCount(CallExpr *Call, unsigned DesiredArgCount) {160 unsigned ArgCount = Call->getNumArgs();161 if (ArgCount == DesiredArgCount)162 return false;163 164 if (checkArgCountAtLeast(Call, DesiredArgCount))165 return true;166 assert(ArgCount > DesiredArgCount && "should have diagnosed this");167 168 // Highlight all the excess arguments.169 SourceRange Range(Call->getArg(DesiredArgCount)->getBeginLoc(),170 Call->getArg(ArgCount - 1)->getEndLoc());171 172 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)173 << 0 /*function call*/ << DesiredArgCount << ArgCount174 << /*is non object*/ 0 << Range;175}176 177static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S) {178 bool HasError = false;179 180 for (const Expr *Arg : Call->arguments()) {181 if (Arg->isValueDependent())182 continue;183 184 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.Context);185 int DiagMsgKind = -1;186 // Arguments must be pointers to constant strings and cannot use '$'.187 if (!ArgString.has_value())188 DiagMsgKind = 0;189 else if (ArgString->find('$') != std::string::npos)190 DiagMsgKind = 1;191 192 if (DiagMsgKind >= 0) {193 S.Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)194 << DiagMsgKind << Arg->getSourceRange();195 HasError = true;196 }197 }198 199 return !HasError;200}201 202static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty) {203 if (Value->isTypeDependent())204 return false;205 206 InitializedEntity Entity =207 InitializedEntity::InitializeParameter(S.Context, Ty, false);208 ExprResult Result =209 S.PerformCopyInitialization(Entity, SourceLocation(), Value);210 if (Result.isInvalid())211 return true;212 Value = Result.get();213 return false;214}215 216/// Check that the first argument to __builtin_annotation is an integer217/// and the second argument is a non-wide string literal.218static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall) {219 if (S.checkArgCount(TheCall, 2))220 return true;221 222 // First argument should be an integer.223 Expr *ValArg = TheCall->getArg(0);224 QualType Ty = ValArg->getType();225 if (!Ty->isIntegerType()) {226 S.Diag(ValArg->getBeginLoc(), diag::err_builtin_annotation_first_arg)227 << ValArg->getSourceRange();228 return true;229 }230 231 // Second argument should be a constant string.232 Expr *StrArg = TheCall->getArg(1)->IgnoreParenCasts();233 StringLiteral *Literal = dyn_cast<StringLiteral>(StrArg);234 if (!Literal || !Literal->isOrdinary()) {235 S.Diag(StrArg->getBeginLoc(), diag::err_builtin_annotation_second_arg)236 << StrArg->getSourceRange();237 return true;238 }239 240 TheCall->setType(Ty);241 return false;242}243 244static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall) {245 // We need at least one argument.246 if (TheCall->getNumArgs() < 1) {247 S.Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)248 << 0 << 1 << TheCall->getNumArgs() << /*is non object*/ 0249 << TheCall->getCallee()->getSourceRange();250 return true;251 }252 253 // All arguments should be wide string literals.254 for (Expr *Arg : TheCall->arguments()) {255 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());256 if (!Literal || !Literal->isWide()) {257 S.Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)258 << Arg->getSourceRange();259 return true;260 }261 }262 263 return false;264}265 266/// Check that the argument to __builtin_addressof is a glvalue, and set the267/// result type to the corresponding pointer type.268static bool BuiltinAddressof(Sema &S, CallExpr *TheCall) {269 if (S.checkArgCount(TheCall, 1))270 return true;271 272 ExprResult Arg(TheCall->getArg(0));273 QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getBeginLoc());274 if (ResultType.isNull())275 return true;276 277 TheCall->setArg(0, Arg.get());278 TheCall->setType(ResultType);279 return false;280}281 282/// Check that the argument to __builtin_function_start is a function.283static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall) {284 if (S.checkArgCount(TheCall, 1))285 return true;286 287 if (TheCall->getArg(0)->containsErrors())288 return true;289 290 ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));291 if (Arg.isInvalid())292 return true;293 294 TheCall->setArg(0, Arg.get());295 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(296 Arg.get()->getAsBuiltinConstantDeclRef(S.getASTContext()));297 298 if (!FD) {299 S.Diag(TheCall->getBeginLoc(), diag::err_function_start_invalid_type)300 << TheCall->getSourceRange();301 return true;302 }303 304 return !S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,305 TheCall->getBeginLoc());306}307 308/// Check the number of arguments and set the result type to309/// the argument type.310static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall) {311 if (S.checkArgCount(TheCall, 1))312 return true;313 314 TheCall->setType(TheCall->getArg(0)->getType());315 return false;316}317 318/// Check that the value argument for __builtin_is_aligned(value, alignment) and319/// __builtin_aligned_{up,down}(value, alignment) is an integer or a pointer320/// type (but not a function pointer) and that the alignment is a power-of-two.321static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) {322 if (S.checkArgCount(TheCall, 2))323 return true;324 325 clang::Expr *Source = TheCall->getArg(0);326 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;327 328 auto IsValidIntegerType = [](QualType Ty) {329 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();330 };331 QualType SrcTy = Source->getType();332 // We should also be able to use it with arrays (but not functions!).333 if (SrcTy->canDecayToPointerType() && SrcTy->isArrayType()) {334 SrcTy = S.Context.getDecayedType(SrcTy);335 }336 if ((!SrcTy->isPointerType() && !IsValidIntegerType(SrcTy)) ||337 SrcTy->isFunctionPointerType()) {338 // FIXME: this is not quite the right error message since we don't allow339 // floating point types, or member pointers.340 S.Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)341 << SrcTy;342 return true;343 }344 345 clang::Expr *AlignOp = TheCall->getArg(1);346 if (!IsValidIntegerType(AlignOp->getType())) {347 S.Diag(AlignOp->getExprLoc(), diag::err_typecheck_expect_int)348 << AlignOp->getType();349 return true;350 }351 Expr::EvalResult AlignResult;352 unsigned MaxAlignmentBits = S.Context.getIntWidth(SrcTy) - 1;353 // We can't check validity of alignment if it is value dependent.354 if (!AlignOp->isValueDependent() &&355 AlignOp->EvaluateAsInt(AlignResult, S.Context,356 Expr::SE_AllowSideEffects)) {357 llvm::APSInt AlignValue = AlignResult.Val.getInt();358 llvm::APSInt MaxValue(359 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));360 if (AlignValue < 1) {361 S.Diag(AlignOp->getExprLoc(), diag::err_alignment_too_small) << 1;362 return true;363 }364 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {365 S.Diag(AlignOp->getExprLoc(), diag::err_alignment_too_big)366 << toString(MaxValue, 10);367 return true;368 }369 if (!AlignValue.isPowerOf2()) {370 S.Diag(AlignOp->getExprLoc(), diag::err_alignment_not_power_of_two);371 return true;372 }373 if (AlignValue == 1) {374 S.Diag(AlignOp->getExprLoc(), diag::warn_alignment_builtin_useless)375 << IsBooleanAlignBuiltin;376 }377 }378 379 ExprResult SrcArg = S.PerformCopyInitialization(380 InitializedEntity::InitializeParameter(S.Context, SrcTy, false),381 SourceLocation(), Source);382 if (SrcArg.isInvalid())383 return true;384 TheCall->setArg(0, SrcArg.get());385 ExprResult AlignArg =386 S.PerformCopyInitialization(InitializedEntity::InitializeParameter(387 S.Context, AlignOp->getType(), false),388 SourceLocation(), AlignOp);389 if (AlignArg.isInvalid())390 return true;391 TheCall->setArg(1, AlignArg.get());392 // For align_up/align_down, the return type is the same as the (potentially393 // decayed) argument type including qualifiers. For is_aligned(), the result394 // is always bool.395 TheCall->setType(IsBooleanAlignBuiltin ? S.Context.BoolTy : SrcTy);396 return false;397}398 399static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID) {400 if (S.checkArgCount(TheCall, 3))401 return true;402 403 std::pair<unsigned, const char *> Builtins[] = {404 { Builtin::BI__builtin_add_overflow, "ckd_add" },405 { Builtin::BI__builtin_sub_overflow, "ckd_sub" },406 { Builtin::BI__builtin_mul_overflow, "ckd_mul" },407 };408 409 bool CkdOperation = llvm::any_of(Builtins, [&](const std::pair<unsigned,410 const char *> &P) {411 return BuiltinID == P.first && TheCall->getExprLoc().isMacroID() &&412 Lexer::getImmediateMacroName(TheCall->getExprLoc(),413 S.getSourceManager(), S.getLangOpts()) == P.second;414 });415 416 auto ValidCkdIntType = [](QualType QT) {417 // A valid checked integer type is an integer type other than a plain char,418 // bool, a bit-precise type, or an enumeration type.419 if (const auto *BT = QT.getCanonicalType()->getAs<BuiltinType>())420 return (BT->getKind() >= BuiltinType::Short &&421 BT->getKind() <= BuiltinType::Int128) || (422 BT->getKind() >= BuiltinType::UShort &&423 BT->getKind() <= BuiltinType::UInt128) ||424 BT->getKind() == BuiltinType::UChar ||425 BT->getKind() == BuiltinType::SChar;426 return false;427 };428 429 // First two arguments should be integers.430 for (unsigned I = 0; I < 2; ++I) {431 ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(I));432 if (Arg.isInvalid()) return true;433 TheCall->setArg(I, Arg.get());434 435 QualType Ty = Arg.get()->getType();436 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->isIntegerType();437 if (!IsValid) {438 S.Diag(Arg.get()->getBeginLoc(), diag::err_overflow_builtin_must_be_int)439 << CkdOperation << Ty << Arg.get()->getSourceRange();440 return true;441 }442 }443 444 // Third argument should be a pointer to a non-const integer.445 // IRGen correctly handles volatile, restrict, and address spaces, and446 // the other qualifiers aren't possible.447 {448 ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(2));449 if (Arg.isInvalid()) return true;450 TheCall->setArg(2, Arg.get());451 452 QualType Ty = Arg.get()->getType();453 const auto *PtrTy = Ty->getAs<PointerType>();454 if (!PtrTy ||455 !PtrTy->getPointeeType()->isIntegerType() ||456 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||457 PtrTy->getPointeeType().isConstQualified()) {458 S.Diag(Arg.get()->getBeginLoc(),459 diag::err_overflow_builtin_must_be_ptr_int)460 << CkdOperation << Ty << Arg.get()->getSourceRange();461 return true;462 }463 }464 465 // Disallow signed bit-precise integer args larger than 128 bits to mul466 // function until we improve backend support.467 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {468 for (unsigned I = 0; I < 3; ++I) {469 const auto Arg = TheCall->getArg(I);470 // Third argument will be a pointer.471 auto Ty = I < 2 ? Arg->getType() : Arg->getType()->getPointeeType();472 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&473 S.getASTContext().getIntWidth(Ty) > 128)474 return S.Diag(Arg->getBeginLoc(),475 diag::err_overflow_builtin_bit_int_max_size)476 << 128;477 }478 }479 480 return false;481}482 483namespace {484struct BuiltinDumpStructGenerator {485 Sema &S;486 CallExpr *TheCall;487 SourceLocation Loc = TheCall->getBeginLoc();488 SmallVector<Expr *, 32> Actions;489 DiagnosticErrorTrap ErrorTracker;490 PrintingPolicy Policy;491 492 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)493 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),494 Policy(S.Context.getPrintingPolicy()) {495 Policy.AnonymousTagLocations = false;496 }497 498 Expr *makeOpaqueValueExpr(Expr *Inner) {499 auto *OVE = new (S.Context)500 OpaqueValueExpr(Loc, Inner->getType(), Inner->getValueKind(),501 Inner->getObjectKind(), Inner);502 Actions.push_back(OVE);503 return OVE;504 }505 506 Expr *getStringLiteral(llvm::StringRef Str) {507 Expr *Lit = S.Context.getPredefinedStringLiteralFromCache(Str);508 // Wrap the literal in parentheses to attach a source location.509 return new (S.Context) ParenExpr(Loc, Loc, Lit);510 }511 512 bool callPrintFunction(llvm::StringRef Format,513 llvm::ArrayRef<Expr *> Exprs = {}) {514 SmallVector<Expr *, 8> Args;515 assert(TheCall->getNumArgs() >= 2);516 Args.reserve((TheCall->getNumArgs() - 2) + /*Format*/ 1 + Exprs.size());517 Args.assign(TheCall->arg_begin() + 2, TheCall->arg_end());518 Args.push_back(getStringLiteral(Format));519 llvm::append_range(Args, Exprs);520 521 // Register a note to explain why we're performing the call.522 Sema::CodeSynthesisContext Ctx;523 Ctx.Kind = Sema::CodeSynthesisContext::BuildingBuiltinDumpStructCall;524 Ctx.PointOfInstantiation = Loc;525 Ctx.CallArgs = Args.data();526 Ctx.NumCallArgs = Args.size();527 S.pushCodeSynthesisContext(Ctx);528 529 ExprResult RealCall =530 S.BuildCallExpr(/*Scope=*/nullptr, TheCall->getArg(1),531 TheCall->getBeginLoc(), Args, TheCall->getRParenLoc());532 533 S.popCodeSynthesisContext();534 if (!RealCall.isInvalid())535 Actions.push_back(RealCall.get());536 // Bail out if we've hit any errors, even if we managed to build the537 // call. We don't want to produce more than one error.538 return RealCall.isInvalid() || ErrorTracker.hasErrorOccurred();539 }540 541 Expr *getIndentString(unsigned Depth) {542 if (!Depth)543 return nullptr;544 545 llvm::SmallString<32> Indent;546 Indent.resize(Depth * Policy.Indentation, ' ');547 return getStringLiteral(Indent);548 }549 550 Expr *getTypeString(QualType T) {551 return getStringLiteral(T.getAsString(Policy));552 }553 554 bool appendFormatSpecifier(QualType T, llvm::SmallVectorImpl<char> &Str) {555 llvm::raw_svector_ostream OS(Str);556 557 // Format 'bool', 'char', 'signed char', 'unsigned char' as numbers, rather558 // than trying to print a single character.559 if (auto *BT = T->getAs<BuiltinType>()) {560 switch (BT->getKind()) {561 case BuiltinType::Bool:562 OS << "%d";563 return true;564 case BuiltinType::Char_U:565 case BuiltinType::UChar:566 OS << "%hhu";567 return true;568 case BuiltinType::Char_S:569 case BuiltinType::SChar:570 OS << "%hhd";571 return true;572 default:573 break;574 }575 }576 577 analyze_printf::PrintfSpecifier Specifier;578 if (Specifier.fixType(T, S.getLangOpts(), S.Context, /*IsObjCLiteral=*/false)) {579 // We were able to guess how to format this.580 if (Specifier.getConversionSpecifier().getKind() ==581 analyze_printf::PrintfConversionSpecifier::sArg) {582 // Wrap double-quotes around a '%s' specifier and limit its maximum583 // length. Ideally we'd also somehow escape special characters in the584 // contents but printf doesn't support that.585 // FIXME: '%s' formatting is not safe in general.586 OS << '"';587 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));588 Specifier.toString(OS);589 OS << '"';590 // FIXME: It would be nice to include a '...' if the string doesn't fit591 // in the length limit.592 } else {593 Specifier.toString(OS);594 }595 return true;596 }597 598 if (T->isPointerType()) {599 // Format all pointers with '%p'.600 OS << "%p";601 return true;602 }603 604 return false;605 }606 607 bool dumpUnnamedRecord(const RecordDecl *RD, Expr *E, unsigned Depth) {608 Expr *IndentLit = getIndentString(Depth);609 Expr *TypeLit = getTypeString(S.Context.getCanonicalTagType(RD));610 if (IndentLit ? callPrintFunction("%s%s", {IndentLit, TypeLit})611 : callPrintFunction("%s", {TypeLit}))612 return true;613 614 return dumpRecordValue(RD, E, IndentLit, Depth);615 }616 617 // Dump a record value. E should be a pointer or lvalue referring to an RD.618 bool dumpRecordValue(const RecordDecl *RD, Expr *E, Expr *RecordIndent,619 unsigned Depth) {620 // FIXME: Decide what to do if RD is a union. At least we should probably621 // turn off printing `const char*` members with `%s`, because that is very622 // likely to crash if that's not the active member. Whatever we decide, we623 // should document it.624 625 // Build an OpaqueValueExpr so we can refer to E more than once without626 // triggering re-evaluation.627 Expr *RecordArg = makeOpaqueValueExpr(E);628 bool RecordArgIsPtr = RecordArg->getType()->isPointerType();629 630 if (callPrintFunction(" {\n"))631 return true;632 633 // Dump each base class, regardless of whether they're aggregates.634 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {635 for (const auto &Base : CXXRD->bases()) {636 QualType BaseType =637 RecordArgIsPtr ? S.Context.getPointerType(Base.getType())638 : S.Context.getLValueReferenceType(Base.getType());639 ExprResult BasePtr = S.BuildCStyleCastExpr(640 Loc, S.Context.getTrivialTypeSourceInfo(BaseType, Loc), Loc,641 RecordArg);642 if (BasePtr.isInvalid() ||643 dumpUnnamedRecord(Base.getType()->getAsRecordDecl(), BasePtr.get(),644 Depth + 1))645 return true;646 }647 }648 649 Expr *FieldIndentArg = getIndentString(Depth + 1);650 651 // Dump each field.652 for (auto *D : RD->decls()) {653 auto *IFD = dyn_cast<IndirectFieldDecl>(D);654 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);655 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())656 continue;657 658 llvm::SmallString<20> Format = llvm::StringRef("%s%s %s ");659 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,660 getTypeString(FD->getType()),661 getStringLiteral(FD->getName())};662 663 if (FD->isBitField()) {664 Format += ": %zu ";665 QualType SizeT = S.Context.getSizeType();666 llvm::APInt BitWidth(S.Context.getIntWidth(SizeT),667 FD->getBitWidthValue());668 Args.push_back(IntegerLiteral::Create(S.Context, BitWidth, SizeT, Loc));669 }670 671 Format += "=";672 673 ExprResult Field =674 IFD ? S.BuildAnonymousStructUnionMemberReference(675 CXXScopeSpec(), Loc, IFD,676 DeclAccessPair::make(IFD, AS_public), RecordArg, Loc)677 : S.BuildFieldReferenceExpr(678 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,679 DeclAccessPair::make(FD, AS_public),680 DeclarationNameInfo(FD->getDeclName(), Loc));681 if (Field.isInvalid())682 return true;683 684 auto *InnerRD = FD->getType()->getAsRecordDecl();685 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);686 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {687 // Recursively print the values of members of aggregate record type.688 if (callPrintFunction(Format, Args) ||689 dumpRecordValue(InnerRD, Field.get(), FieldIndentArg, Depth + 1))690 return true;691 } else {692 Format += " ";693 if (appendFormatSpecifier(FD->getType(), Format)) {694 // We know how to print this field.695 Args.push_back(Field.get());696 } else {697 // We don't know how to print this field. Print out its address698 // with a format specifier that a smart tool will be able to699 // recognize and treat specially.700 Format += "*%p";701 ExprResult FieldAddr =702 S.BuildUnaryOp(nullptr, Loc, UO_AddrOf, Field.get());703 if (FieldAddr.isInvalid())704 return true;705 Args.push_back(FieldAddr.get());706 }707 Format += "\n";708 if (callPrintFunction(Format, Args))709 return true;710 }711 }712 713 return RecordIndent ? callPrintFunction("%s}\n", RecordIndent)714 : callPrintFunction("}\n");715 }716 717 Expr *buildWrapper() {718 auto *Wrapper = PseudoObjectExpr::Create(S.Context, TheCall, Actions,719 PseudoObjectExpr::NoResult);720 TheCall->setType(Wrapper->getType());721 TheCall->setValueKind(Wrapper->getValueKind());722 return Wrapper;723 }724};725} // namespace726 727static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall) {728 if (S.checkArgCountAtLeast(TheCall, 2))729 return ExprError();730 731 ExprResult PtrArgResult = S.DefaultLvalueConversion(TheCall->getArg(0));732 if (PtrArgResult.isInvalid())733 return ExprError();734 TheCall->setArg(0, PtrArgResult.get());735 736 // First argument should be a pointer to a struct.737 QualType PtrArgType = PtrArgResult.get()->getType();738 if (!PtrArgType->isPointerType() ||739 !PtrArgType->getPointeeType()->isRecordType()) {740 S.Diag(PtrArgResult.get()->getBeginLoc(),741 diag::err_expected_struct_pointer_argument)742 << 1 << TheCall->getDirectCallee() << PtrArgType;743 return ExprError();744 }745 QualType Pointee = PtrArgType->getPointeeType();746 const RecordDecl *RD = Pointee->getAsRecordDecl();747 // Try to instantiate the class template as appropriate; otherwise, access to748 // its data() may lead to a crash.749 if (S.RequireCompleteType(PtrArgResult.get()->getBeginLoc(), Pointee,750 diag::err_incomplete_type))751 return ExprError();752 // Second argument is a callable, but we can't fully validate it until we try753 // calling it.754 QualType FnArgType = TheCall->getArg(1)->getType();755 if (!FnArgType->isFunctionType() && !FnArgType->isFunctionPointerType() &&756 !FnArgType->isBlockPointerType() &&757 !(S.getLangOpts().CPlusPlus && FnArgType->isRecordType())) {758 auto *BT = FnArgType->getAs<BuiltinType>();759 switch (BT ? BT->getKind() : BuiltinType::Void) {760 case BuiltinType::Dependent:761 case BuiltinType::Overload:762 case BuiltinType::BoundMember:763 case BuiltinType::PseudoObject:764 case BuiltinType::UnknownAny:765 case BuiltinType::BuiltinFn:766 // This might be a callable.767 break;768 769 default:770 S.Diag(TheCall->getArg(1)->getBeginLoc(),771 diag::err_expected_callable_argument)772 << 2 << TheCall->getDirectCallee() << FnArgType;773 return ExprError();774 }775 }776 777 BuiltinDumpStructGenerator Generator(S, TheCall);778 779 // Wrap parentheses around the given pointer. This is not necessary for780 // correct code generation, but it means that when we pretty-print the call781 // arguments in our diagnostics we will produce '(&s)->n' instead of the782 // incorrect '&s->n'.783 Expr *PtrArg = PtrArgResult.get();784 PtrArg = new (S.Context)785 ParenExpr(PtrArg->getBeginLoc(),786 S.getLocForEndOfToken(PtrArg->getEndLoc()), PtrArg);787 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))788 return ExprError();789 790 return Generator.buildWrapper();791}792 793static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) {794 if (S.checkArgCount(BuiltinCall, 2))795 return true;796 797 SourceLocation BuiltinLoc = BuiltinCall->getBeginLoc();798 Expr *Builtin = BuiltinCall->getCallee()->IgnoreImpCasts();799 Expr *Call = BuiltinCall->getArg(0);800 Expr *Chain = BuiltinCall->getArg(1);801 802 if (Call->getStmtClass() != Stmt::CallExprClass) {803 S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)804 << Call->getSourceRange();805 return true;806 }807 808 auto CE = cast<CallExpr>(Call);809 if (CE->getCallee()->getType()->isBlockPointerType()) {810 S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)811 << Call->getSourceRange();812 return true;813 }814 815 const Decl *TargetDecl = CE->getCalleeDecl();816 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))817 if (FD->getBuiltinID()) {818 S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)819 << Call->getSourceRange();820 return true;821 }822 823 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {824 S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)825 << Call->getSourceRange();826 return true;827 }828 829 ExprResult ChainResult = S.UsualUnaryConversions(Chain);830 if (ChainResult.isInvalid())831 return true;832 if (!ChainResult.get()->getType()->isPointerType()) {833 S.Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)834 << Chain->getSourceRange();835 return true;836 }837 838 QualType ReturnTy = CE->getCallReturnType(S.Context);839 QualType ArgTys[2] = { ReturnTy, ChainResult.get()->getType() };840 QualType BuiltinTy = S.Context.getFunctionType(841 ReturnTy, ArgTys, FunctionProtoType::ExtProtoInfo());842 QualType BuiltinPtrTy = S.Context.getPointerType(BuiltinTy);843 844 Builtin =845 S.ImpCastExprToType(Builtin, BuiltinPtrTy, CK_BuiltinFnToFnPtr).get();846 847 BuiltinCall->setType(CE->getType());848 BuiltinCall->setValueKind(CE->getValueKind());849 BuiltinCall->setObjectKind(CE->getObjectKind());850 BuiltinCall->setCallee(Builtin);851 BuiltinCall->setArg(1, ChainResult.get());852 853 return false;854}855 856namespace {857 858class ScanfDiagnosticFormatHandler859 : public analyze_format_string::FormatStringHandler {860 // Accepts the argument index (relative to the first destination index) of the861 // argument whose size we want.862 using ComputeSizeFunction =863 llvm::function_ref<std::optional<llvm::APSInt>(unsigned)>;864 865 // Accepts the argument index (relative to the first destination index), the866 // destination size, and the source size).867 using DiagnoseFunction =868 llvm::function_ref<void(unsigned, unsigned, unsigned)>;869 870 ComputeSizeFunction ComputeSizeArgument;871 DiagnoseFunction Diagnose;872 873public:874 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,875 DiagnoseFunction Diagnose)876 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}877 878 bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,879 const char *StartSpecifier,880 unsigned specifierLen) override {881 if (!FS.consumesDataArgument())882 return true;883 884 unsigned NulByte = 0;885 switch ((FS.getConversionSpecifier().getKind())) {886 default:887 return true;888 case analyze_format_string::ConversionSpecifier::sArg:889 case analyze_format_string::ConversionSpecifier::ScanListArg:890 NulByte = 1;891 break;892 case analyze_format_string::ConversionSpecifier::cArg:893 break;894 }895 896 analyze_format_string::OptionalAmount FW = FS.getFieldWidth();897 if (FW.getHowSpecified() !=898 analyze_format_string::OptionalAmount::HowSpecified::Constant)899 return true;900 901 unsigned SourceSize = FW.getConstantAmount() + NulByte;902 903 std::optional<llvm::APSInt> DestSizeAPS =904 ComputeSizeArgument(FS.getArgIndex());905 if (!DestSizeAPS)906 return true;907 908 unsigned DestSize = DestSizeAPS->getZExtValue();909 910 if (DestSize < SourceSize)911 Diagnose(FS.getArgIndex(), DestSize, SourceSize);912 913 return true;914 }915};916 917class EstimateSizeFormatHandler918 : public analyze_format_string::FormatStringHandler {919 size_t Size;920 /// Whether the format string contains Linux kernel's format specifier921 /// extension.922 bool IsKernelCompatible = true;923 924public:925 EstimateSizeFormatHandler(StringRef Format)926 : Size(std::min(Format.find(0), Format.size()) +927 1 /* null byte always written by sprintf */) {}928 929 bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,930 const char *, unsigned SpecifierLen,931 const TargetInfo &) override {932 933 const size_t FieldWidth = computeFieldWidth(FS);934 const size_t Precision = computePrecision(FS);935 936 // The actual format.937 switch (FS.getConversionSpecifier().getKind()) {938 // Just a char.939 case analyze_format_string::ConversionSpecifier::cArg:940 case analyze_format_string::ConversionSpecifier::CArg:941 Size += std::max(FieldWidth, (size_t)1);942 break;943 // Just an integer.944 case analyze_format_string::ConversionSpecifier::dArg:945 case analyze_format_string::ConversionSpecifier::DArg:946 case analyze_format_string::ConversionSpecifier::iArg:947 case analyze_format_string::ConversionSpecifier::oArg:948 case analyze_format_string::ConversionSpecifier::OArg:949 case analyze_format_string::ConversionSpecifier::uArg:950 case analyze_format_string::ConversionSpecifier::UArg:951 case analyze_format_string::ConversionSpecifier::xArg:952 case analyze_format_string::ConversionSpecifier::XArg:953 Size += std::max(FieldWidth, Precision);954 break;955 956 // %g style conversion switches between %f or %e style dynamically.957 // %g removes trailing zeros, and does not print decimal point if there are958 // no digits that follow it. Thus %g can print a single digit.959 // FIXME: If it is alternative form:960 // For g and G conversions, trailing zeros are not removed from the result.961 case analyze_format_string::ConversionSpecifier::gArg:962 case analyze_format_string::ConversionSpecifier::GArg:963 Size += 1;964 break;965 966 // Floating point number in the form '[+]ddd.ddd'.967 case analyze_format_string::ConversionSpecifier::fArg:968 case analyze_format_string::ConversionSpecifier::FArg:969 Size += std::max(FieldWidth, 1 /* integer part */ +970 (Precision ? 1 + Precision971 : 0) /* period + decimal */);972 break;973 974 // Floating point number in the form '[-]d.ddde[+-]dd'.975 case analyze_format_string::ConversionSpecifier::eArg:976 case analyze_format_string::ConversionSpecifier::EArg:977 Size +=978 std::max(FieldWidth,979 1 /* integer part */ +980 (Precision ? 1 + Precision : 0) /* period + decimal */ +981 1 /* e or E letter */ + 2 /* exponent */);982 break;983 984 // Floating point number in the form '[-]0xh.hhhhp±dd'.985 case analyze_format_string::ConversionSpecifier::aArg:986 case analyze_format_string::ConversionSpecifier::AArg:987 Size +=988 std::max(FieldWidth,989 2 /* 0x */ + 1 /* integer part */ +990 (Precision ? 1 + Precision : 0) /* period + decimal */ +991 1 /* p or P letter */ + 1 /* + or - */ + 1 /* value */);992 break;993 994 // Just a string.995 case analyze_format_string::ConversionSpecifier::sArg:996 case analyze_format_string::ConversionSpecifier::SArg:997 Size += FieldWidth;998 break;999 1000 // Just a pointer in the form '0xddd'.1001 case analyze_format_string::ConversionSpecifier::pArg:1002 // Linux kernel has its own extesion for `%p` specifier.1003 // Kernel Document:1004 // https://docs.kernel.org/core-api/printk-formats.html#pointer-types1005 IsKernelCompatible = false;1006 Size += std::max(FieldWidth, 2 /* leading 0x */ + Precision);1007 break;1008 1009 // A plain percent.1010 case analyze_format_string::ConversionSpecifier::PercentArg:1011 Size += 1;1012 break;1013 1014 default:1015 break;1016 }1017 1018 // If field width is specified, the sign/space is already accounted for1019 // within the field width, so no additional size is needed.1020 if ((FS.hasPlusPrefix() || FS.hasSpacePrefix()) && FieldWidth == 0)1021 Size += 1;1022 1023 if (FS.hasAlternativeForm()) {1024 switch (FS.getConversionSpecifier().getKind()) {1025 // For o conversion, it increases the precision, if and only if necessary,1026 // to force the first digit of the result to be a zero1027 // (if the value and precision are both 0, a single 0 is printed)1028 case analyze_format_string::ConversionSpecifier::oArg:1029 // For b conversion, a nonzero result has 0b prefixed to it.1030 case analyze_format_string::ConversionSpecifier::bArg:1031 // For x (or X) conversion, a nonzero result has 0x (or 0X) prefixed to1032 // it.1033 case analyze_format_string::ConversionSpecifier::xArg:1034 case analyze_format_string::ConversionSpecifier::XArg:1035 // Note: even when the prefix is added, if1036 // (prefix_width <= FieldWidth - formatted_length) holds,1037 // the prefix does not increase the format1038 // size. e.g.(("%#3x", 0xf) is "0xf")1039 1040 // If the result is zero, o, b, x, X adds nothing.1041 break;1042 // For a, A, e, E, f, F, g, and G conversions,1043 // the result of converting a floating-point number always contains a1044 // decimal-point1045 case analyze_format_string::ConversionSpecifier::aArg:1046 case analyze_format_string::ConversionSpecifier::AArg:1047 case analyze_format_string::ConversionSpecifier::eArg:1048 case analyze_format_string::ConversionSpecifier::EArg:1049 case analyze_format_string::ConversionSpecifier::fArg:1050 case analyze_format_string::ConversionSpecifier::FArg:1051 case analyze_format_string::ConversionSpecifier::gArg:1052 case analyze_format_string::ConversionSpecifier::GArg:1053 Size += (Precision ? 0 : 1);1054 break;1055 // For other conversions, the behavior is undefined.1056 default:1057 break;1058 }1059 }1060 assert(SpecifierLen <= Size && "no underflow");1061 Size -= SpecifierLen;1062 return true;1063 }1064 1065 size_t getSizeLowerBound() const { return Size; }1066 bool isKernelCompatible() const { return IsKernelCompatible; }1067 1068private:1069 static size_t computeFieldWidth(const analyze_printf::PrintfSpecifier &FS) {1070 const analyze_format_string::OptionalAmount &FW = FS.getFieldWidth();1071 size_t FieldWidth = 0;1072 if (FW.getHowSpecified() == analyze_format_string::OptionalAmount::Constant)1073 FieldWidth = FW.getConstantAmount();1074 return FieldWidth;1075 }1076 1077 static size_t computePrecision(const analyze_printf::PrintfSpecifier &FS) {1078 const analyze_format_string::OptionalAmount &FW = FS.getPrecision();1079 size_t Precision = 0;1080 1081 // See man 3 printf for default precision value based on the specifier.1082 switch (FW.getHowSpecified()) {1083 case analyze_format_string::OptionalAmount::NotSpecified:1084 switch (FS.getConversionSpecifier().getKind()) {1085 default:1086 break;1087 case analyze_format_string::ConversionSpecifier::dArg: // %d1088 case analyze_format_string::ConversionSpecifier::DArg: // %D1089 case analyze_format_string::ConversionSpecifier::iArg: // %i1090 Precision = 1;1091 break;1092 case analyze_format_string::ConversionSpecifier::oArg: // %d1093 case analyze_format_string::ConversionSpecifier::OArg: // %D1094 case analyze_format_string::ConversionSpecifier::uArg: // %d1095 case analyze_format_string::ConversionSpecifier::UArg: // %D1096 case analyze_format_string::ConversionSpecifier::xArg: // %d1097 case analyze_format_string::ConversionSpecifier::XArg: // %D1098 Precision = 1;1099 break;1100 case analyze_format_string::ConversionSpecifier::fArg: // %f1101 case analyze_format_string::ConversionSpecifier::FArg: // %F1102 case analyze_format_string::ConversionSpecifier::eArg: // %e1103 case analyze_format_string::ConversionSpecifier::EArg: // %E1104 case analyze_format_string::ConversionSpecifier::gArg: // %g1105 case analyze_format_string::ConversionSpecifier::GArg: // %G1106 Precision = 6;1107 break;1108 case analyze_format_string::ConversionSpecifier::pArg: // %d1109 Precision = 1;1110 break;1111 }1112 break;1113 case analyze_format_string::OptionalAmount::Constant:1114 Precision = FW.getConstantAmount();1115 break;1116 default:1117 break;1118 }1119 return Precision;1120 }1121};1122 1123} // namespace1124 1125static bool ProcessFormatStringLiteral(const Expr *FormatExpr,1126 StringRef &FormatStrRef, size_t &StrLen,1127 ASTContext &Context) {1128 if (const auto *Format = dyn_cast<StringLiteral>(FormatExpr);1129 Format && (Format->isOrdinary() || Format->isUTF8())) {1130 FormatStrRef = Format->getString();1131 const ConstantArrayType *T =1132 Context.getAsConstantArrayType(Format->getType());1133 assert(T && "String literal not of constant array type!");1134 size_t TypeSize = T->getZExtSize();1135 // In case there's a null byte somewhere.1136 StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, FormatStrRef.find(0));1137 return true;1138 }1139 return false;1140}1141 1142void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD,1143 CallExpr *TheCall) {1144 if (TheCall->isValueDependent() || TheCall->isTypeDependent() ||1145 isConstantEvaluatedContext())1146 return;1147 1148 bool UseDABAttr = false;1149 const FunctionDecl *UseDecl = FD;1150 1151 const auto *DABAttr = FD->getAttr<DiagnoseAsBuiltinAttr>();1152 if (DABAttr) {1153 UseDecl = DABAttr->getFunction();1154 assert(UseDecl && "Missing FunctionDecl in DiagnoseAsBuiltin attribute!");1155 UseDABAttr = true;1156 }1157 1158 unsigned BuiltinID = UseDecl->getBuiltinID(/*ConsiderWrappers=*/true);1159 1160 if (!BuiltinID)1161 return;1162 1163 const TargetInfo &TI = getASTContext().getTargetInfo();1164 unsigned SizeTypeWidth = TI.getTypeWidth(TI.getSizeType());1165 1166 auto TranslateIndex = [&](unsigned Index) -> std::optional<unsigned> {1167 // If we refer to a diagnose_as_builtin attribute, we need to change the1168 // argument index to refer to the arguments of the called function. Unless1169 // the index is out of bounds, which presumably means it's a variadic1170 // function.1171 if (!UseDABAttr)1172 return Index;1173 unsigned DABIndices = DABAttr->argIndices_size();1174 unsigned NewIndex = Index < DABIndices1175 ? DABAttr->argIndices_begin()[Index]1176 : Index - DABIndices + FD->getNumParams();1177 if (NewIndex >= TheCall->getNumArgs())1178 return std::nullopt;1179 return NewIndex;1180 };1181 1182 auto ComputeExplicitObjectSizeArgument =1183 [&](unsigned Index) -> std::optional<llvm::APSInt> {1184 std::optional<unsigned> IndexOptional = TranslateIndex(Index);1185 if (!IndexOptional)1186 return std::nullopt;1187 unsigned NewIndex = *IndexOptional;1188 Expr::EvalResult Result;1189 Expr *SizeArg = TheCall->getArg(NewIndex);1190 if (!SizeArg->EvaluateAsInt(Result, getASTContext()))1191 return std::nullopt;1192 llvm::APSInt Integer = Result.Val.getInt();1193 Integer.setIsUnsigned(true);1194 return Integer;1195 };1196 1197 auto ComputeSizeArgument =1198 [&](unsigned Index) -> std::optional<llvm::APSInt> {1199 // If the parameter has a pass_object_size attribute, then we should use its1200 // (potentially) more strict checking mode. Otherwise, conservatively assume1201 // type 0.1202 int BOSType = 0;1203 // This check can fail for variadic functions.1204 if (Index < FD->getNumParams()) {1205 if (const auto *POS =1206 FD->getParamDecl(Index)->getAttr<PassObjectSizeAttr>())1207 BOSType = POS->getType();1208 }1209 1210 std::optional<unsigned> IndexOptional = TranslateIndex(Index);1211 if (!IndexOptional)1212 return std::nullopt;1213 unsigned NewIndex = *IndexOptional;1214 1215 if (NewIndex >= TheCall->getNumArgs())1216 return std::nullopt;1217 1218 const Expr *ObjArg = TheCall->getArg(NewIndex);1219 uint64_t Result;1220 if (!ObjArg->tryEvaluateObjectSize(Result, getASTContext(), BOSType))1221 return std::nullopt;1222 1223 // Get the object size in the target's size_t width.1224 return llvm::APSInt::getUnsigned(Result).extOrTrunc(SizeTypeWidth);1225 };1226 1227 auto ComputeStrLenArgument =1228 [&](unsigned Index) -> std::optional<llvm::APSInt> {1229 std::optional<unsigned> IndexOptional = TranslateIndex(Index);1230 if (!IndexOptional)1231 return std::nullopt;1232 unsigned NewIndex = *IndexOptional;1233 1234 const Expr *ObjArg = TheCall->getArg(NewIndex);1235 uint64_t Result;1236 if (!ObjArg->tryEvaluateStrLen(Result, getASTContext()))1237 return std::nullopt;1238 // Add 1 for null byte.1239 return llvm::APSInt::getUnsigned(Result + 1).extOrTrunc(SizeTypeWidth);1240 };1241 1242 std::optional<llvm::APSInt> SourceSize;1243 std::optional<llvm::APSInt> DestinationSize;1244 unsigned DiagID = 0;1245 bool IsChkVariant = false;1246 1247 auto GetFunctionName = [&]() {1248 std::string FunctionNameStr =1249 getASTContext().BuiltinInfo.getName(BuiltinID);1250 llvm::StringRef FunctionName = FunctionNameStr;1251 // Skim off the details of whichever builtin was called to produce a better1252 // diagnostic, as it's unlikely that the user wrote the __builtin1253 // explicitly.1254 if (IsChkVariant) {1255 FunctionName = FunctionName.drop_front(std::strlen("__builtin___"));1256 FunctionName = FunctionName.drop_back(std::strlen("_chk"));1257 } else {1258 FunctionName.consume_front("__builtin_");1259 }1260 return FunctionName.str();1261 };1262 1263 switch (BuiltinID) {1264 default:1265 return;1266 case Builtin::BI__builtin_strcat:1267 case Builtin::BIstrcat:1268 case Builtin::BI__builtin_stpcpy:1269 case Builtin::BIstpcpy:1270 case Builtin::BI__builtin_strcpy:1271 case Builtin::BIstrcpy: {1272 DiagID = diag::warn_fortify_strlen_overflow;1273 SourceSize = ComputeStrLenArgument(1);1274 DestinationSize = ComputeSizeArgument(0);1275 break;1276 }1277 1278 case Builtin::BI__builtin___strcat_chk:1279 case Builtin::BI__builtin___stpcpy_chk:1280 case Builtin::BI__builtin___strcpy_chk: {1281 DiagID = diag::warn_fortify_strlen_overflow;1282 SourceSize = ComputeStrLenArgument(1);1283 DestinationSize = ComputeExplicitObjectSizeArgument(2);1284 IsChkVariant = true;1285 break;1286 }1287 1288 case Builtin::BIscanf:1289 case Builtin::BIfscanf:1290 case Builtin::BIsscanf: {1291 unsigned FormatIndex = 1;1292 unsigned DataIndex = 2;1293 if (BuiltinID == Builtin::BIscanf) {1294 FormatIndex = 0;1295 DataIndex = 1;1296 }1297 1298 const auto *FormatExpr =1299 TheCall->getArg(FormatIndex)->IgnoreParenImpCasts();1300 1301 StringRef FormatStrRef;1302 size_t StrLen;1303 if (!ProcessFormatStringLiteral(FormatExpr, FormatStrRef, StrLen, Context))1304 return;1305 1306 auto Diagnose = [&](unsigned ArgIndex, unsigned DestSize,1307 unsigned SourceSize) {1308 DiagID = diag::warn_fortify_scanf_overflow;1309 unsigned Index = ArgIndex + DataIndex;1310 std::string FunctionName = GetFunctionName();1311 DiagRuntimeBehavior(TheCall->getArg(Index)->getBeginLoc(), TheCall,1312 PDiag(DiagID) << FunctionName << (Index + 1)1313 << DestSize << SourceSize);1314 };1315 1316 auto ShiftedComputeSizeArgument = [&](unsigned Index) {1317 return ComputeSizeArgument(Index + DataIndex);1318 };1319 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument, Diagnose);1320 const char *FormatBytes = FormatStrRef.data();1321 analyze_format_string::ParseScanfString(H, FormatBytes,1322 FormatBytes + StrLen, getLangOpts(),1323 Context.getTargetInfo());1324 1325 // Unlike the other cases, in this one we have already issued the diagnostic1326 // here, so no need to continue (because unlike the other cases, here the1327 // diagnostic refers to the argument number).1328 return;1329 }1330 1331 case Builtin::BIsprintf:1332 case Builtin::BI__builtin___sprintf_chk: {1333 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;1334 auto *FormatExpr = TheCall->getArg(FormatIndex)->IgnoreParenImpCasts();1335 1336 StringRef FormatStrRef;1337 size_t StrLen;1338 if (ProcessFormatStringLiteral(FormatExpr, FormatStrRef, StrLen, Context)) {1339 EstimateSizeFormatHandler H(FormatStrRef);1340 const char *FormatBytes = FormatStrRef.data();1341 if (!analyze_format_string::ParsePrintfString(1342 H, FormatBytes, FormatBytes + StrLen, getLangOpts(),1343 Context.getTargetInfo(), false)) {1344 DiagID = H.isKernelCompatible()1345 ? diag::warn_format_overflow1346 : diag::warn_format_overflow_non_kprintf;1347 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())1348 .extOrTrunc(SizeTypeWidth);1349 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {1350 DestinationSize = ComputeExplicitObjectSizeArgument(2);1351 IsChkVariant = true;1352 } else {1353 DestinationSize = ComputeSizeArgument(0);1354 }1355 break;1356 }1357 }1358 return;1359 }1360 case Builtin::BI__builtin___memcpy_chk:1361 case Builtin::BI__builtin___memmove_chk:1362 case Builtin::BI__builtin___memset_chk:1363 case Builtin::BI__builtin___strlcat_chk:1364 case Builtin::BI__builtin___strlcpy_chk:1365 case Builtin::BI__builtin___strncat_chk:1366 case Builtin::BI__builtin___strncpy_chk:1367 case Builtin::BI__builtin___stpncpy_chk:1368 case Builtin::BI__builtin___memccpy_chk:1369 case Builtin::BI__builtin___mempcpy_chk: {1370 DiagID = diag::warn_builtin_chk_overflow;1371 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 2);1372 DestinationSize =1373 ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1);1374 IsChkVariant = true;1375 break;1376 }1377 1378 case Builtin::BI__builtin___snprintf_chk:1379 case Builtin::BI__builtin___vsnprintf_chk: {1380 DiagID = diag::warn_builtin_chk_overflow;1381 SourceSize = ComputeExplicitObjectSizeArgument(1);1382 DestinationSize = ComputeExplicitObjectSizeArgument(3);1383 IsChkVariant = true;1384 break;1385 }1386 1387 case Builtin::BIstrncat:1388 case Builtin::BI__builtin_strncat:1389 case Builtin::BIstrncpy:1390 case Builtin::BI__builtin_strncpy:1391 case Builtin::BIstpncpy:1392 case Builtin::BI__builtin_stpncpy: {1393 // Whether these functions overflow depends on the runtime strlen of the1394 // string, not just the buffer size, so emitting the "always overflow"1395 // diagnostic isn't quite right. We should still diagnose passing a buffer1396 // size larger than the destination buffer though; this is a runtime abort1397 // in _FORTIFY_SOURCE mode, and is quite suspicious otherwise.1398 DiagID = diag::warn_fortify_source_size_mismatch;1399 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1);1400 DestinationSize = ComputeSizeArgument(0);1401 break;1402 }1403 1404 case Builtin::BImemcpy:1405 case Builtin::BI__builtin_memcpy:1406 case Builtin::BImemmove:1407 case Builtin::BI__builtin_memmove:1408 case Builtin::BImemset:1409 case Builtin::BI__builtin_memset:1410 case Builtin::BImempcpy:1411 case Builtin::BI__builtin_mempcpy: {1412 DiagID = diag::warn_fortify_source_overflow;1413 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1);1414 DestinationSize = ComputeSizeArgument(0);1415 break;1416 }1417 case Builtin::BIsnprintf:1418 case Builtin::BI__builtin_snprintf:1419 case Builtin::BIvsnprintf:1420 case Builtin::BI__builtin_vsnprintf: {1421 DiagID = diag::warn_fortify_source_size_mismatch;1422 SourceSize = ComputeExplicitObjectSizeArgument(1);1423 const auto *FormatExpr = TheCall->getArg(2)->IgnoreParenImpCasts();1424 StringRef FormatStrRef;1425 size_t StrLen;1426 if (SourceSize &&1427 ProcessFormatStringLiteral(FormatExpr, FormatStrRef, StrLen, Context)) {1428 EstimateSizeFormatHandler H(FormatStrRef);1429 const char *FormatBytes = FormatStrRef.data();1430 if (!analyze_format_string::ParsePrintfString(1431 H, FormatBytes, FormatBytes + StrLen, getLangOpts(),1432 Context.getTargetInfo(), /*isFreeBSDKPrintf=*/false)) {1433 llvm::APSInt FormatSize =1434 llvm::APSInt::getUnsigned(H.getSizeLowerBound())1435 .extOrTrunc(SizeTypeWidth);1436 if (FormatSize > *SourceSize && *SourceSize != 0) {1437 unsigned TruncationDiagID =1438 H.isKernelCompatible() ? diag::warn_format_truncation1439 : diag::warn_format_truncation_non_kprintf;1440 SmallString<16> SpecifiedSizeStr;1441 SmallString<16> FormatSizeStr;1442 SourceSize->toString(SpecifiedSizeStr, /*Radix=*/10);1443 FormatSize.toString(FormatSizeStr, /*Radix=*/10);1444 DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall,1445 PDiag(TruncationDiagID)1446 << GetFunctionName() << SpecifiedSizeStr1447 << FormatSizeStr);1448 }1449 }1450 }1451 DestinationSize = ComputeSizeArgument(0);1452 }1453 }1454 1455 if (!SourceSize || !DestinationSize ||1456 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)1457 return;1458 1459 std::string FunctionName = GetFunctionName();1460 1461 SmallString<16> DestinationStr;1462 SmallString<16> SourceStr;1463 DestinationSize->toString(DestinationStr, /*Radix=*/10);1464 SourceSize->toString(SourceStr, /*Radix=*/10);1465 DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall,1466 PDiag(DiagID)1467 << FunctionName << DestinationStr << SourceStr);1468}1469 1470static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall,1471 Scope::ScopeFlags NeededScopeFlags,1472 unsigned DiagID) {1473 // Scopes aren't available during instantiation. Fortunately, builtin1474 // functions cannot be template args so they cannot be formed through template1475 // instantiation. Therefore checking once during the parse is sufficient.1476 if (SemaRef.inTemplateInstantiation())1477 return false;1478 1479 Scope *S = SemaRef.getCurScope();1480 while (S && !S->isSEHExceptScope())1481 S = S->getParent();1482 if (!S || !(S->getFlags() & NeededScopeFlags)) {1483 auto *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());1484 SemaRef.Diag(TheCall->getExprLoc(), DiagID)1485 << DRE->getDecl()->getIdentifier();1486 return true;1487 }1488 1489 return false;1490}1491 1492// In OpenCL, __builtin_alloca_* should return a pointer to address space1493// that corresponds to the stack address space i.e private address space.1494static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall) {1495 QualType RT = TheCall->getType();1496 assert((RT->isPointerType() && !(RT->getPointeeType().hasAddressSpace())) &&1497 "__builtin_alloca has invalid address space");1498 1499 RT = RT->getPointeeType();1500 RT = S.Context.getAddrSpaceQualType(RT, LangAS::opencl_private);1501 TheCall->setType(S.Context.getPointerType(RT));1502}1503 1504static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall) {1505 if (S.checkArgCountAtLeast(TheCall, 1))1506 return true;1507 1508 for (Expr *Arg : TheCall->arguments()) {1509 // If argument is dependent on a template parameter, we can't resolve now.1510 if (Arg->isTypeDependent() || Arg->isValueDependent())1511 continue;1512 // Reject void types.1513 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();1514 if (ArgTy->isVoidType())1515 return S.Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);1516 }1517 1518 TheCall->setType(S.Context.getSizeType());1519 return false;1520}1521 1522namespace {1523enum PointerAuthOpKind {1524 PAO_Strip,1525 PAO_Sign,1526 PAO_Auth,1527 PAO_SignGeneric,1528 PAO_Discriminator,1529 PAO_BlendPointer,1530 PAO_BlendInteger1531};1532}1533 1534bool Sema::checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range) {1535 if (getLangOpts().PointerAuthIntrinsics)1536 return false;1537 1538 Diag(Loc, diag::err_ptrauth_disabled) << Range;1539 return true;1540}1541 1542static bool checkPointerAuthEnabled(Sema &S, Expr *E) {1543 return S.checkPointerAuthEnabled(E->getExprLoc(), E->getSourceRange());1544}1545 1546static bool checkPointerAuthKey(Sema &S, Expr *&Arg) {1547 // Convert it to type 'int'.1548 if (convertArgumentToType(S, Arg, S.Context.IntTy))1549 return true;1550 1551 // Value-dependent expressions are okay; wait for template instantiation.1552 if (Arg->isValueDependent())1553 return false;1554 1555 unsigned KeyValue;1556 return S.checkConstantPointerAuthKey(Arg, KeyValue);1557}1558 1559bool Sema::checkConstantPointerAuthKey(Expr *Arg, unsigned &Result) {1560 // Attempt to constant-evaluate the expression.1561 std::optional<llvm::APSInt> KeyValue = Arg->getIntegerConstantExpr(Context);1562 if (!KeyValue) {1563 Diag(Arg->getExprLoc(), diag::err_expr_not_ice)1564 << 0 << Arg->getSourceRange();1565 return true;1566 }1567 1568 // Ask the target to validate the key parameter.1569 if (!Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {1570 llvm::SmallString<32> Value;1571 {1572 llvm::raw_svector_ostream Str(Value);1573 Str << *KeyValue;1574 }1575 1576 Diag(Arg->getExprLoc(), diag::err_ptrauth_invalid_key)1577 << Value << Arg->getSourceRange();1578 return true;1579 }1580 1581 Result = KeyValue->getZExtValue();1582 return false;1583}1584 1585bool Sema::checkPointerAuthDiscriminatorArg(Expr *Arg,1586 PointerAuthDiscArgKind Kind,1587 unsigned &IntVal) {1588 if (!Arg) {1589 IntVal = 0;1590 return true;1591 }1592 1593 std::optional<llvm::APSInt> Result = Arg->getIntegerConstantExpr(Context);1594 if (!Result) {1595 Diag(Arg->getExprLoc(), diag::err_ptrauth_arg_not_ice);1596 return false;1597 }1598 1599 unsigned Max;1600 bool IsAddrDiscArg = false;1601 1602 switch (Kind) {1603 case PointerAuthDiscArgKind::Addr:1604 Max = 1;1605 IsAddrDiscArg = true;1606 break;1607 case PointerAuthDiscArgKind::Extra:1608 Max = PointerAuthQualifier::MaxDiscriminator;1609 break;1610 };1611 1612 if (*Result < 0 || *Result > Max) {1613 if (IsAddrDiscArg)1614 Diag(Arg->getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)1615 << Result->getExtValue();1616 else1617 Diag(Arg->getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)1618 << Result->getExtValue() << Max;1619 1620 return false;1621 };1622 1623 IntVal = Result->getZExtValue();1624 return true;1625}1626 1627static std::pair<const ValueDecl *, CharUnits>1628findConstantBaseAndOffset(Sema &S, Expr *E) {1629 // Must evaluate as a pointer.1630 Expr::EvalResult Result;1631 if (!E->EvaluateAsRValue(Result, S.Context) || !Result.Val.isLValue())1632 return {nullptr, CharUnits()};1633 1634 const auto *BaseDecl =1635 Result.Val.getLValueBase().dyn_cast<const ValueDecl *>();1636 if (!BaseDecl)1637 return {nullptr, CharUnits()};1638 1639 return {BaseDecl, Result.Val.getLValueOffset()};1640}1641 1642static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind,1643 bool RequireConstant = false) {1644 if (Arg->hasPlaceholderType()) {1645 ExprResult R = S.CheckPlaceholderExpr(Arg);1646 if (R.isInvalid())1647 return true;1648 Arg = R.get();1649 }1650 1651 auto AllowsPointer = [](PointerAuthOpKind OpKind) {1652 return OpKind != PAO_BlendInteger;1653 };1654 auto AllowsInteger = [](PointerAuthOpKind OpKind) {1655 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||1656 OpKind == PAO_SignGeneric;1657 };1658 1659 // Require the value to have the right range of type.1660 QualType ExpectedTy;1661 if (AllowsPointer(OpKind) && Arg->getType()->isPointerType()) {1662 ExpectedTy = Arg->getType().getUnqualifiedType();1663 } else if (AllowsPointer(OpKind) && Arg->getType()->isNullPtrType()) {1664 ExpectedTy = S.Context.VoidPtrTy;1665 } else if (AllowsInteger(OpKind) &&1666 Arg->getType()->isIntegralOrUnscopedEnumerationType()) {1667 ExpectedTy = S.Context.getUIntPtrType();1668 1669 } else {1670 // Diagnose the failures.1671 S.Diag(Arg->getExprLoc(), diag::err_ptrauth_value_bad_type)1672 << unsigned(OpKind == PAO_Discriminator ? 11673 : OpKind == PAO_BlendPointer ? 21674 : OpKind == PAO_BlendInteger ? 31675 : 0)1676 << unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)1677 << Arg->getType() << Arg->getSourceRange();1678 return true;1679 }1680 1681 // Convert to that type. This should just be an lvalue-to-rvalue1682 // conversion.1683 if (convertArgumentToType(S, Arg, ExpectedTy))1684 return true;1685 1686 if (!RequireConstant) {1687 // Warn about null pointers for non-generic sign and auth operations.1688 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&1689 Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) {1690 S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign1691 ? diag::warn_ptrauth_sign_null_pointer1692 : diag::warn_ptrauth_auth_null_pointer)1693 << Arg->getSourceRange();1694 }1695 1696 return false;1697 }1698 1699 // Perform special checking on the arguments to ptrauth_sign_constant.1700 1701 // The main argument.1702 if (OpKind == PAO_Sign) {1703 // Require the value we're signing to have a special form.1704 auto [BaseDecl, Offset] = findConstantBaseAndOffset(S, Arg);1705 bool Invalid;1706 1707 // Must be rooted in a declaration reference.1708 if (!BaseDecl)1709 Invalid = true;1710 1711 // If it's a function declaration, we can't have an offset.1712 else if (isa<FunctionDecl>(BaseDecl))1713 Invalid = !Offset.isZero();1714 1715 // Otherwise we're fine.1716 else1717 Invalid = false;1718 1719 if (Invalid)1720 S.Diag(Arg->getExprLoc(), diag::err_ptrauth_bad_constant_pointer);1721 return Invalid;1722 }1723 1724 // The discriminator argument.1725 assert(OpKind == PAO_Discriminator);1726 1727 // Must be a pointer or integer or blend thereof.1728 Expr *Pointer = nullptr;1729 Expr *Integer = nullptr;1730 if (auto *Call = dyn_cast<CallExpr>(Arg->IgnoreParens())) {1731 if (Call->getBuiltinCallee() ==1732 Builtin::BI__builtin_ptrauth_blend_discriminator) {1733 Pointer = Call->getArg(0);1734 Integer = Call->getArg(1);1735 }1736 }1737 if (!Pointer && !Integer) {1738 if (Arg->getType()->isPointerType())1739 Pointer = Arg;1740 else1741 Integer = Arg;1742 }1743 1744 // Check the pointer.1745 bool Invalid = false;1746 if (Pointer) {1747 assert(Pointer->getType()->isPointerType());1748 1749 // TODO: if we're initializing a global, check that the address is1750 // somehow related to what we're initializing. This probably will1751 // never really be feasible and we'll have to catch it at link-time.1752 auto [BaseDecl, Offset] = findConstantBaseAndOffset(S, Pointer);1753 if (!BaseDecl || !isa<VarDecl>(BaseDecl))1754 Invalid = true;1755 }1756 1757 // Check the integer.1758 if (Integer) {1759 assert(Integer->getType()->isIntegerType());1760 if (!Integer->isEvaluatable(S.Context))1761 Invalid = true;1762 }1763 1764 if (Invalid)1765 S.Diag(Arg->getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);1766 return Invalid;1767}1768 1769static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call) {1770 if (S.checkArgCount(Call, 2))1771 return ExprError();1772 if (checkPointerAuthEnabled(S, Call))1773 return ExprError();1774 if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_Strip) ||1775 checkPointerAuthKey(S, Call->getArgs()[1]))1776 return ExprError();1777 1778 Call->setType(Call->getArgs()[0]->getType());1779 return Call;1780}1781 1782static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call) {1783 if (S.checkArgCount(Call, 2))1784 return ExprError();1785 if (checkPointerAuthEnabled(S, Call))1786 return ExprError();1787 if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_BlendPointer) ||1788 checkPointerAuthValue(S, Call->getArgs()[1], PAO_BlendInteger))1789 return ExprError();1790 1791 Call->setType(S.Context.getUIntPtrType());1792 return Call;1793}1794 1795static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call) {1796 if (S.checkArgCount(Call, 2))1797 return ExprError();1798 if (checkPointerAuthEnabled(S, Call))1799 return ExprError();1800 if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_SignGeneric) ||1801 checkPointerAuthValue(S, Call->getArgs()[1], PAO_Discriminator))1802 return ExprError();1803 1804 Call->setType(S.Context.getUIntPtrType());1805 return Call;1806}1807 1808static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call,1809 PointerAuthOpKind OpKind,1810 bool RequireConstant) {1811 if (S.checkArgCount(Call, 3))1812 return ExprError();1813 if (checkPointerAuthEnabled(S, Call))1814 return ExprError();1815 if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind, RequireConstant) ||1816 checkPointerAuthKey(S, Call->getArgs()[1]) ||1817 checkPointerAuthValue(S, Call->getArgs()[2], PAO_Discriminator,1818 RequireConstant))1819 return ExprError();1820 1821 Call->setType(Call->getArgs()[0]->getType());1822 return Call;1823}1824 1825static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) {1826 if (S.checkArgCount(Call, 5))1827 return ExprError();1828 if (checkPointerAuthEnabled(S, Call))1829 return ExprError();1830 if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_Auth) ||1831 checkPointerAuthKey(S, Call->getArgs()[1]) ||1832 checkPointerAuthValue(S, Call->getArgs()[2], PAO_Discriminator) ||1833 checkPointerAuthKey(S, Call->getArgs()[3]) ||1834 checkPointerAuthValue(S, Call->getArgs()[4], PAO_Discriminator))1835 return ExprError();1836 1837 Call->setType(Call->getArgs()[0]->getType());1838 return Call;1839}1840 1841static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call) {1842 if (checkPointerAuthEnabled(S, Call))1843 return ExprError();1844 1845 // We've already performed normal call type-checking.1846 const Expr *Arg = Call->getArg(0)->IgnoreParenImpCasts();1847 1848 // Operand must be an ordinary or UTF-8 string literal.1849 const auto *Literal = dyn_cast<StringLiteral>(Arg);1850 if (!Literal || Literal->getCharByteWidth() != 1) {1851 S.Diag(Arg->getExprLoc(), diag::err_ptrauth_string_not_literal)1852 << (Literal ? 1 : 0) << Arg->getSourceRange();1853 return ExprError();1854 }1855 1856 return Call;1857}1858 1859static ExprResult GetVTablePointer(Sema &S, CallExpr *Call) {1860 if (S.checkArgCount(Call, 1))1861 return ExprError();1862 Expr *FirstArg = Call->getArg(0);1863 ExprResult FirstValue = S.DefaultFunctionArrayLvalueConversion(FirstArg);1864 if (FirstValue.isInvalid())1865 return ExprError();1866 Call->setArg(0, FirstValue.get());1867 QualType FirstArgType = FirstArg->getType();1868 if (FirstArgType->canDecayToPointerType() && FirstArgType->isArrayType())1869 FirstArgType = S.Context.getDecayedType(FirstArgType);1870 1871 const CXXRecordDecl *FirstArgRecord = FirstArgType->getPointeeCXXRecordDecl();1872 if (!FirstArgRecord) {1873 S.Diag(FirstArg->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)1874 << /*isPolymorphic=*/0 << FirstArgType;1875 return ExprError();1876 }1877 if (S.RequireCompleteType(1878 FirstArg->getBeginLoc(), FirstArgType->getPointeeType(),1879 diag::err_get_vtable_pointer_requires_complete_type)) {1880 return ExprError();1881 }1882 1883 if (!FirstArgRecord->isPolymorphic()) {1884 S.Diag(FirstArg->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)1885 << /*isPolymorphic=*/1 << FirstArgRecord;1886 return ExprError();1887 }1888 QualType ReturnType = S.Context.getPointerType(S.Context.VoidTy.withConst());1889 Call->setType(ReturnType);1890 return Call;1891}1892 1893static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall) {1894 if (S.checkArgCount(TheCall, 1))1895 return ExprError();1896 1897 // Compute __builtin_launder's parameter type from the argument.1898 // The parameter type is:1899 // * The type of the argument if it's not an array or function type,1900 // Otherwise,1901 // * The decayed argument type.1902 QualType ParamTy = [&]() {1903 QualType ArgTy = TheCall->getArg(0)->getType();1904 if (const ArrayType *Ty = ArgTy->getAsArrayTypeUnsafe())1905 return S.Context.getPointerType(Ty->getElementType());1906 if (ArgTy->isFunctionType()) {1907 return S.Context.getPointerType(ArgTy);1908 }1909 return ArgTy;1910 }();1911 1912 TheCall->setType(ParamTy);1913 1914 auto DiagSelect = [&]() -> std::optional<unsigned> {1915 if (!ParamTy->isPointerType())1916 return 0;1917 if (ParamTy->isFunctionPointerType())1918 return 1;1919 if (ParamTy->isVoidPointerType())1920 return 2;1921 return std::optional<unsigned>{};1922 }();1923 if (DiagSelect) {1924 S.Diag(TheCall->getBeginLoc(), diag::err_builtin_launder_invalid_arg)1925 << *DiagSelect << TheCall->getSourceRange();1926 return ExprError();1927 }1928 1929 // We either have an incomplete class type, or we have a class template1930 // whose instantiation has not been forced. Example:1931 //1932 // template <class T> struct Foo { T value; };1933 // Foo<int> *p = nullptr;1934 // auto *d = __builtin_launder(p);1935 if (S.RequireCompleteType(TheCall->getBeginLoc(), ParamTy->getPointeeType(),1936 diag::err_incomplete_type))1937 return ExprError();1938 1939 assert(ParamTy->getPointeeType()->isObjectType() &&1940 "Unhandled non-object pointer case");1941 1942 InitializedEntity Entity =1943 InitializedEntity::InitializeParameter(S.Context, ParamTy, false);1944 ExprResult Arg =1945 S.PerformCopyInitialization(Entity, SourceLocation(), TheCall->getArg(0));1946 if (Arg.isInvalid())1947 return ExprError();1948 TheCall->setArg(0, Arg.get());1949 1950 return TheCall;1951}1952 1953static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall) {1954 if (S.checkArgCount(TheCall, 1))1955 return ExprError();1956 1957 ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));1958 if (Arg.isInvalid())1959 return ExprError();1960 QualType ParamTy = Arg.get()->getType();1961 TheCall->setArg(0, Arg.get());1962 TheCall->setType(S.Context.BoolTy);1963 1964 // Only accept pointers to objects as arguments, which should have object1965 // pointer or void pointer types.1966 if (const auto *PT = ParamTy->getAs<PointerType>()) {1967 // LWG4138: Function pointer types not allowed1968 if (PT->getPointeeType()->isFunctionType()) {1969 S.Diag(TheCall->getArg(0)->getExprLoc(),1970 diag::err_builtin_is_within_lifetime_invalid_arg)1971 << 1;1972 return ExprError();1973 }1974 // Disallow VLAs too since those shouldn't be able to1975 // be a template parameter for `std::is_within_lifetime`1976 if (PT->getPointeeType()->isVariableArrayType()) {1977 S.Diag(TheCall->getArg(0)->getExprLoc(), diag::err_vla_unsupported)1978 << 1 << "__builtin_is_within_lifetime";1979 return ExprError();1980 }1981 } else {1982 S.Diag(TheCall->getArg(0)->getExprLoc(),1983 diag::err_builtin_is_within_lifetime_invalid_arg)1984 << 0;1985 return ExprError();1986 }1987 return TheCall;1988}1989 1990static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall) {1991 if (S.checkArgCount(TheCall, 3))1992 return ExprError();1993 1994 QualType Dest = TheCall->getArg(0)->getType();1995 if (!Dest->isPointerType() || Dest.getCVRQualifiers() != 0) {1996 S.Diag(TheCall->getArg(0)->getExprLoc(),1997 diag::err_builtin_trivially_relocate_invalid_arg_type)1998 << /*a pointer*/ 0;1999 return ExprError();2000 }2001 2002 QualType T = Dest->getPointeeType();2003 if (S.RequireCompleteType(TheCall->getBeginLoc(), T,2004 diag::err_incomplete_type))2005 return ExprError();2006 2007 if (T.isConstQualified() || !S.IsCXXTriviallyRelocatableType(T) ||2008 T->isIncompleteArrayType()) {2009 S.Diag(TheCall->getArg(0)->getExprLoc(),2010 diag::err_builtin_trivially_relocate_invalid_arg_type)2011 << (T.isConstQualified() ? /*non-const*/ 1 : /*relocatable*/ 2);2012 return ExprError();2013 }2014 2015 TheCall->setType(Dest);2016 2017 QualType Src = TheCall->getArg(1)->getType();2018 if (Src.getCanonicalType() != Dest.getCanonicalType()) {2019 S.Diag(TheCall->getArg(1)->getExprLoc(),2020 diag::err_builtin_trivially_relocate_invalid_arg_type)2021 << /*the same*/ 3;2022 return ExprError();2023 }2024 2025 Expr *SizeExpr = TheCall->getArg(2);2026 ExprResult Size = S.DefaultLvalueConversion(SizeExpr);2027 if (Size.isInvalid())2028 return ExprError();2029 2030 Size = S.tryConvertExprToType(Size.get(), S.getASTContext().getSizeType());2031 if (Size.isInvalid())2032 return ExprError();2033 SizeExpr = Size.get();2034 TheCall->setArg(2, SizeExpr);2035 2036 return TheCall;2037}2038 2039// Emit an error and return true if the current object format type is in the2040// list of unsupported types.2041static bool CheckBuiltinTargetNotInUnsupported(2042 Sema &S, unsigned BuiltinID, CallExpr *TheCall,2043 ArrayRef<llvm::Triple::ObjectFormatType> UnsupportedObjectFormatTypes) {2044 llvm::Triple::ObjectFormatType CurObjFormat =2045 S.getASTContext().getTargetInfo().getTriple().getObjectFormat();2046 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {2047 S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)2048 << TheCall->getSourceRange();2049 return true;2050 }2051 return false;2052}2053 2054// Emit an error and return true if the current architecture is not in the list2055// of supported architectures.2056static bool2057CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall,2058 ArrayRef<llvm::Triple::ArchType> SupportedArchs) {2059 llvm::Triple::ArchType CurArch =2060 S.getASTContext().getTargetInfo().getTriple().getArch();2061 if (llvm::is_contained(SupportedArchs, CurArch))2062 return false;2063 S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)2064 << TheCall->getSourceRange();2065 return true;2066}2067 2068static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr,2069 SourceLocation CallSiteLoc);2070 2071bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,2072 CallExpr *TheCall) {2073 switch (TI.getTriple().getArch()) {2074 default:2075 // Some builtins don't require additional checking, so just consider these2076 // acceptable.2077 return false;2078 case llvm::Triple::arm:2079 case llvm::Triple::armeb:2080 case llvm::Triple::thumb:2081 case llvm::Triple::thumbeb:2082 return ARM().CheckARMBuiltinFunctionCall(TI, BuiltinID, TheCall);2083 case llvm::Triple::aarch64:2084 case llvm::Triple::aarch64_32:2085 case llvm::Triple::aarch64_be:2086 return ARM().CheckAArch64BuiltinFunctionCall(TI, BuiltinID, TheCall);2087 case llvm::Triple::bpfeb:2088 case llvm::Triple::bpfel:2089 return BPF().CheckBPFBuiltinFunctionCall(BuiltinID, TheCall);2090 case llvm::Triple::dxil:2091 return DirectX().CheckDirectXBuiltinFunctionCall(BuiltinID, TheCall);2092 case llvm::Triple::hexagon:2093 return Hexagon().CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall);2094 case llvm::Triple::mips:2095 case llvm::Triple::mipsel:2096 case llvm::Triple::mips64:2097 case llvm::Triple::mips64el:2098 return MIPS().CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall);2099 case llvm::Triple::spirv:2100 case llvm::Triple::spirv32:2101 case llvm::Triple::spirv64:2102 if (TI.getTriple().getOS() != llvm::Triple::OSType::AMDHSA)2103 return SPIRV().CheckSPIRVBuiltinFunctionCall(TI, BuiltinID, TheCall);2104 return false;2105 case llvm::Triple::systemz:2106 return SystemZ().CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall);2107 case llvm::Triple::x86:2108 case llvm::Triple::x86_64:2109 return X86().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall);2110 case llvm::Triple::ppc:2111 case llvm::Triple::ppcle:2112 case llvm::Triple::ppc64:2113 case llvm::Triple::ppc64le:2114 return PPC().CheckPPCBuiltinFunctionCall(TI, BuiltinID, TheCall);2115 case llvm::Triple::amdgcn:2116 return AMDGPU().CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall);2117 case llvm::Triple::riscv32:2118 case llvm::Triple::riscv64:2119 return RISCV().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall);2120 case llvm::Triple::loongarch32:2121 case llvm::Triple::loongarch64:2122 return LoongArch().CheckLoongArchBuiltinFunctionCall(TI, BuiltinID,2123 TheCall);2124 case llvm::Triple::wasm32:2125 case llvm::Triple::wasm64:2126 return Wasm().CheckWebAssemblyBuiltinFunctionCall(TI, BuiltinID, TheCall);2127 case llvm::Triple::nvptx:2128 case llvm::Triple::nvptx64:2129 return NVPTX().CheckNVPTXBuiltinFunctionCall(TI, BuiltinID, TheCall);2130 }2131}2132 2133// Check if \p Ty is a valid type for the elementwise math builtins. If it is2134// not a valid type, emit an error message and return true. Otherwise return2135// false.2136static bool2137checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy,2138 Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr,2139 int ArgOrdinal) {2140 QualType EltTy = ArgTy;2141 if (auto *VecTy = EltTy->getAs<VectorType>())2142 EltTy = VecTy->getElementType();2143 2144 switch (ArgTyRestr) {2145 case Sema::EltwiseBuiltinArgTyRestriction::None:2146 if (!ArgTy->getAs<VectorType>() &&2147 !ConstantMatrixType::isValidElementType(ArgTy)) {2148 return S.Diag(Loc, diag::err_builtin_invalid_arg_type)2149 << ArgOrdinal << /* vector */ 2 << /* integer */ 1 << /* fp */ 12150 << ArgTy;2151 }2152 break;2153 case Sema::EltwiseBuiltinArgTyRestriction::FloatTy:2154 if (!EltTy->isRealFloatingType()) {2155 return S.Diag(Loc, diag::err_builtin_invalid_arg_type)2156 << ArgOrdinal << /* scalar or vector */ 5 << /* no int */ 02157 << /* floating-point */ 1 << ArgTy;2158 }2159 break;2160 case Sema::EltwiseBuiltinArgTyRestriction::IntegerTy:2161 if (!EltTy->isIntegerType()) {2162 return S.Diag(Loc, diag::err_builtin_invalid_arg_type)2163 << ArgOrdinal << /* scalar or vector */ 5 << /* integer */ 12164 << /* no fp */ 0 << ArgTy;2165 }2166 break;2167 case Sema::EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy:2168 if (EltTy->isUnsignedIntegerType()) {2169 return S.Diag(Loc, diag::err_builtin_invalid_arg_type)2170 << 1 << /* scalar or vector */ 5 << /* signed int */ 22171 << /* or fp */ 1 << ArgTy;2172 }2173 break;2174 }2175 2176 return false;2177}2178 2179/// BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).2180/// This checks that the target supports the builtin and that the string2181/// argument is constant and valid.2182static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall,2183 const TargetInfo *AuxTI, unsigned BuiltinID) {2184 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||2185 BuiltinID == Builtin::BI__builtin_cpu_is) &&2186 "Expecting __builtin_cpu_...");2187 2188 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;2189 const TargetInfo *TheTI = &TI;2190 auto SupportsBI = [=](const TargetInfo *TInfo) {2191 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||2192 (!IsCPUSupports && TInfo->supportsCpuIs()));2193 };2194 if (!SupportsBI(&TI) && SupportsBI(AuxTI))2195 TheTI = AuxTI;2196 2197 if ((!IsCPUSupports && !TheTI->supportsCpuIs()) ||2198 (IsCPUSupports && !TheTI->supportsCpuSupports()))2199 return S.Diag(TheCall->getBeginLoc(),2200 TI.getTriple().isOSAIX()2201 ? diag::err_builtin_aix_os_unsupported2202 : diag::err_builtin_target_unsupported)2203 << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());2204 2205 Expr *Arg = TheCall->getArg(0)->IgnoreParenImpCasts();2206 // Check if the argument is a string literal.2207 if (!isa<StringLiteral>(Arg))2208 return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)2209 << Arg->getSourceRange();2210 2211 // Check the contents of the string.2212 StringRef Feature = cast<StringLiteral>(Arg)->getString();2213 if (IsCPUSupports && !TheTI->validateCpuSupports(Feature)) {2214 S.Diag(TheCall->getBeginLoc(), diag::warn_invalid_cpu_supports)2215 << Arg->getSourceRange();2216 return false;2217 }2218 if (!IsCPUSupports && !TheTI->validateCpuIs(Feature))2219 return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is)2220 << Arg->getSourceRange();2221 return false;2222}2223 2224/// Checks that __builtin_bswapg was called with a single argument, which is an2225/// unsigned integer, and overrides the return value type to the integer type.2226static bool BuiltinBswapg(Sema &S, CallExpr *TheCall) {2227 if (S.checkArgCount(TheCall, 1))2228 return true;2229 ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0));2230 if (ArgRes.isInvalid())2231 return true;2232 2233 Expr *Arg = ArgRes.get();2234 TheCall->setArg(0, Arg);2235 if (Arg->isTypeDependent())2236 return false;2237 2238 QualType ArgTy = Arg->getType();2239 2240 if (!ArgTy->isIntegerType()) {2241 S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)2242 << 1 << /*scalar=*/1 << /*unsigned integer=*/1 << /*floating point=*/02243 << ArgTy;2244 return true;2245 }2246 if (const auto *BT = dyn_cast<BitIntType>(ArgTy)) {2247 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8) {2248 S.Diag(Arg->getBeginLoc(), diag::err_bswapg_invalid_bit_width)2249 << ArgTy << BT->getNumBits();2250 return true;2251 }2252 }2253 TheCall->setType(ArgTy);2254 return false;2255}2256 2257/// Checks that __builtin_popcountg was called with a single argument, which is2258/// an unsigned integer.2259static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) {2260 if (S.checkArgCount(TheCall, 1))2261 return true;2262 2263 ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0));2264 if (ArgRes.isInvalid())2265 return true;2266 2267 Expr *Arg = ArgRes.get();2268 TheCall->setArg(0, Arg);2269 2270 QualType ArgTy = Arg->getType();2271 2272 if (!ArgTy->isUnsignedIntegerType() && !ArgTy->isExtVectorBoolType()) {2273 S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)2274 << 1 << /* scalar */ 1 << /* unsigned integer ty */ 3 << /* no fp */ 02275 << ArgTy;2276 return true;2277 }2278 return false;2279}2280 2281/// Checks that __builtin_{clzg,ctzg} was called with a first argument, which is2282/// an unsigned integer, and an optional second argument, which is promoted to2283/// an 'int'.2284static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) {2285 if (S.checkArgCountRange(TheCall, 1, 2))2286 return true;2287 2288 ExprResult Arg0Res = S.DefaultLvalueConversion(TheCall->getArg(0));2289 if (Arg0Res.isInvalid())2290 return true;2291 2292 Expr *Arg0 = Arg0Res.get();2293 TheCall->setArg(0, Arg0);2294 2295 QualType Arg0Ty = Arg0->getType();2296 2297 if (!Arg0Ty->isUnsignedIntegerType() && !Arg0Ty->isExtVectorBoolType()) {2298 S.Diag(Arg0->getBeginLoc(), diag::err_builtin_invalid_arg_type)2299 << 1 << /* scalar */ 1 << /* unsigned integer ty */ 3 << /* no fp */ 02300 << Arg0Ty;2301 return true;2302 }2303 2304 if (TheCall->getNumArgs() > 1) {2305 ExprResult Arg1Res = S.UsualUnaryConversions(TheCall->getArg(1));2306 if (Arg1Res.isInvalid())2307 return true;2308 2309 Expr *Arg1 = Arg1Res.get();2310 TheCall->setArg(1, Arg1);2311 2312 QualType Arg1Ty = Arg1->getType();2313 2314 if (!Arg1Ty->isSpecificBuiltinType(BuiltinType::Int)) {2315 S.Diag(Arg1->getBeginLoc(), diag::err_builtin_invalid_arg_type)2316 << 2 << /* scalar */ 1 << /* 'int' ty */ 4 << /* no fp */ 0 << Arg1Ty;2317 return true;2318 }2319 }2320 2321 return false;2322}2323 2324static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg,2325 unsigned Pos, bool AllowConst,2326 bool AllowAS) {2327 QualType MaskTy = MaskArg->getType();2328 if (!MaskTy->isExtVectorBoolType())2329 return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)2330 << 1 << /* vector of */ 4 << /* booleans */ 6 << /* no fp */ 02331 << MaskTy;2332 2333 QualType PtrTy = PtrArg->getType();2334 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())2335 return S.Diag(PtrArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)2336 << Pos << "scalar pointer";2337 2338 QualType PointeeTy = PtrTy->getPointeeType();2339 if (PointeeTy.isVolatileQualified() || PointeeTy->isAtomicType() ||2340 (!AllowConst && PointeeTy.isConstQualified()) ||2341 (!AllowAS && PointeeTy.hasAddressSpace())) {2342 QualType Target =2343 S.Context.getPointerType(PointeeTy.getAtomicUnqualifiedType());2344 return S.Diag(PtrArg->getExprLoc(),2345 diag::err_typecheck_convert_incompatible)2346 << PtrTy << Target << /*different qualifiers=*/52347 << /*qualifier difference=*/0 << /*parameter mismatch=*/3 << 22348 << PtrTy << Target;2349 }2350 return false;2351}2352 2353static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall) {2354 bool TypeDependent = false;2355 for (unsigned Arg = 0, E = TheCall->getNumArgs(); Arg != E; ++Arg) {2356 ExprResult Converted =2357 S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(Arg));2358 if (Converted.isInvalid())2359 return true;2360 TheCall->setArg(Arg, Converted.get());2361 TypeDependent |= Converted.get()->isTypeDependent();2362 }2363 2364 if (TypeDependent)2365 TheCall->setType(S.Context.DependentTy);2366 return false;2367}2368 2369static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall) {2370 if (S.checkArgCountRange(TheCall, 2, 3))2371 return ExprError();2372 2373 if (ConvertMaskedBuiltinArgs(S, TheCall))2374 return ExprError();2375 2376 Expr *MaskArg = TheCall->getArg(0);2377 Expr *PtrArg = TheCall->getArg(1);2378 if (TheCall->isTypeDependent())2379 return TheCall;2380 2381 if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 2, /*AllowConst=*/true,2382 TheCall->getBuiltinCallee() ==2383 Builtin::BI__builtin_masked_load))2384 return ExprError();2385 2386 QualType MaskTy = MaskArg->getType();2387 QualType PtrTy = PtrArg->getType();2388 QualType PointeeTy = PtrTy->getPointeeType();2389 const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();2390 2391 QualType RetTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),2392 MaskVecTy->getNumElements());2393 if (TheCall->getNumArgs() == 3) {2394 Expr *PassThruArg = TheCall->getArg(2);2395 QualType PassThruTy = PassThruArg->getType();2396 if (!S.Context.hasSameType(PassThruTy, RetTy))2397 return S.Diag(PtrArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)2398 << /* third argument */ 3 << RetTy;2399 }2400 2401 TheCall->setType(RetTy);2402 return TheCall;2403}2404 2405static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall) {2406 if (S.checkArgCount(TheCall, 3))2407 return ExprError();2408 2409 if (ConvertMaskedBuiltinArgs(S, TheCall))2410 return ExprError();2411 2412 Expr *MaskArg = TheCall->getArg(0);2413 Expr *ValArg = TheCall->getArg(1);2414 Expr *PtrArg = TheCall->getArg(2);2415 if (TheCall->isTypeDependent())2416 return TheCall;2417 2418 if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 3, /*AllowConst=*/false,2419 TheCall->getBuiltinCallee() ==2420 Builtin::BI__builtin_masked_store))2421 return ExprError();2422 2423 QualType MaskTy = MaskArg->getType();2424 QualType PtrTy = PtrArg->getType();2425 QualType ValTy = ValArg->getType();2426 if (!ValTy->isVectorType())2427 return ExprError(2428 S.Diag(ValArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)2429 << 2 << "vector");2430 2431 QualType PointeeTy = PtrTy->getPointeeType();2432 const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();2433 QualType MemoryTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),2434 MaskVecTy->getNumElements());2435 if (!S.Context.hasSameType(ValTy.getUnqualifiedType(),2436 MemoryTy.getUnqualifiedType()))2437 return ExprError(S.Diag(TheCall->getBeginLoc(),2438 diag::err_vec_builtin_incompatible_vector)2439 << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ 22440 << SourceRange(TheCall->getArg(1)->getBeginLoc(),2441 TheCall->getArg(1)->getEndLoc()));2442 2443 TheCall->setType(S.Context.VoidTy);2444 return TheCall;2445}2446 2447static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall) {2448 if (S.checkArgCountRange(TheCall, 3, 4))2449 return ExprError();2450 2451 if (ConvertMaskedBuiltinArgs(S, TheCall))2452 return ExprError();2453 2454 Expr *MaskArg = TheCall->getArg(0);2455 Expr *IdxArg = TheCall->getArg(1);2456 Expr *PtrArg = TheCall->getArg(2);2457 if (TheCall->isTypeDependent())2458 return TheCall;2459 2460 if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 3, /*AllowConst=*/true,2461 /*AllowAS=*/true))2462 return ExprError();2463 2464 QualType IdxTy = IdxArg->getType();2465 const VectorType *IdxVecTy = IdxTy->getAs<VectorType>();2466 if (!IdxTy->isExtVectorType() || !IdxVecTy->getElementType()->isIntegerType())2467 return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)2468 << 1 << /* vector of */ 4 << /* integer */ 1 << /* no fp */ 02469 << IdxTy;2470 2471 QualType MaskTy = MaskArg->getType();2472 QualType PtrTy = PtrArg->getType();2473 QualType PointeeTy = PtrTy->getPointeeType();2474 const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();2475 if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())2476 return ExprError(2477 S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)2478 << S.getASTContext().BuiltinInfo.getQuotedName(2479 TheCall->getBuiltinCallee())2480 << MaskTy << IdxTy);2481 2482 QualType RetTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),2483 MaskVecTy->getNumElements());2484 if (TheCall->getNumArgs() == 4) {2485 Expr *PassThruArg = TheCall->getArg(3);2486 QualType PassThruTy = PassThruArg->getType();2487 if (!S.Context.hasSameType(PassThruTy, RetTy))2488 return S.Diag(PassThruArg->getExprLoc(),2489 diag::err_vec_masked_load_store_ptr)2490 << /* fourth argument */ 4 << RetTy;2491 }2492 2493 TheCall->setType(RetTy);2494 return TheCall;2495}2496 2497static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall) {2498 if (S.checkArgCount(TheCall, 4))2499 return ExprError();2500 2501 if (ConvertMaskedBuiltinArgs(S, TheCall))2502 return ExprError();2503 2504 Expr *MaskArg = TheCall->getArg(0);2505 Expr *IdxArg = TheCall->getArg(1);2506 Expr *ValArg = TheCall->getArg(2);2507 Expr *PtrArg = TheCall->getArg(3);2508 if (TheCall->isTypeDependent())2509 return TheCall;2510 2511 if (CheckMaskedBuiltinArgs(S, MaskArg, PtrArg, 4, /*AllowConst=*/false,2512 /*AllowAS=*/true))2513 return ExprError();2514 2515 QualType IdxTy = IdxArg->getType();2516 const VectorType *IdxVecTy = IdxTy->getAs<VectorType>();2517 if (!IdxTy->isExtVectorType() || !IdxVecTy->getElementType()->isIntegerType())2518 return S.Diag(MaskArg->getBeginLoc(), diag::err_builtin_invalid_arg_type)2519 << 2 << /* vector of */ 4 << /* integer */ 1 << /* no fp */ 02520 << IdxTy;2521 2522 QualType ValTy = ValArg->getType();2523 QualType MaskTy = MaskArg->getType();2524 QualType PtrTy = PtrArg->getType();2525 QualType PointeeTy = PtrTy->getPointeeType();2526 2527 const VectorType *MaskVecTy = MaskTy->castAs<VectorType>();2528 const VectorType *ValVecTy = ValTy->castAs<VectorType>();2529 if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())2530 return ExprError(2531 S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)2532 << S.getASTContext().BuiltinInfo.getQuotedName(2533 TheCall->getBuiltinCallee())2534 << MaskTy << IdxTy);2535 if (MaskVecTy->getNumElements() != ValVecTy->getNumElements())2536 return ExprError(2537 S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)2538 << S.getASTContext().BuiltinInfo.getQuotedName(2539 TheCall->getBuiltinCallee())2540 << MaskTy << ValTy);2541 2542 QualType ArgTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),2543 MaskVecTy->getNumElements());2544 if (!S.Context.hasSameType(ValTy.getUnqualifiedType(), ArgTy))2545 return ExprError(S.Diag(TheCall->getBeginLoc(),2546 diag::err_vec_builtin_incompatible_vector)2547 << TheCall->getDirectCallee() << /*isMoreThanTwoArgs*/ 22548 << SourceRange(TheCall->getArg(1)->getBeginLoc(),2549 TheCall->getArg(1)->getEndLoc()));2550 2551 TheCall->setType(S.Context.VoidTy);2552 return TheCall;2553}2554 2555static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall) {2556 SourceLocation Loc = TheCall->getBeginLoc();2557 MutableArrayRef Args(TheCall->getArgs(), TheCall->getNumArgs());2558 assert(llvm::none_of(Args, [](Expr *Arg) { return Arg->isTypeDependent(); }));2559 2560 if (Args.size() == 0) {2561 S.Diag(TheCall->getBeginLoc(),2562 diag::err_typecheck_call_too_few_args_at_least)2563 << /*callee_type=*/0 << /*min_arg_count=*/1 << /*actual_arg_count=*/02564 << /*is_non_object=*/0 << TheCall->getSourceRange();2565 return ExprError();2566 }2567 2568 QualType FuncT = Args[0]->getType();2569 2570 if (const auto *MPT = FuncT->getAs<MemberPointerType>()) {2571 if (Args.size() < 2) {2572 S.Diag(TheCall->getBeginLoc(),2573 diag::err_typecheck_call_too_few_args_at_least)2574 << /*callee_type=*/0 << /*min_arg_count=*/2 << /*actual_arg_count=*/12575 << /*is_non_object=*/0 << TheCall->getSourceRange();2576 return ExprError();2577 }2578 2579 const Type *MemPtrClass = MPT->getQualifier().getAsType();2580 QualType ObjectT = Args[1]->getType();2581 2582 if (MPT->isMemberDataPointer() && S.checkArgCount(TheCall, 2))2583 return ExprError();2584 2585 ExprResult ObjectArg = [&]() -> ExprResult {2586 // (1.1): (t1.*f)(t2, ..., tN) when f is a pointer to a member function of2587 // a class T and is_same_v<T, remove_cvref_t<decltype(t1)>> ||2588 // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;2589 // (1.4): t1.*f when N=1 and f is a pointer to data member of a class T2590 // and is_same_v<T, remove_cvref_t<decltype(t1)>> ||2591 // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;2592 if (S.Context.hasSameType(QualType(MemPtrClass, 0),2593 S.BuiltinRemoveCVRef(ObjectT, Loc)) ||2594 S.BuiltinIsBaseOf(Args[1]->getBeginLoc(), QualType(MemPtrClass, 0),2595 S.BuiltinRemoveCVRef(ObjectT, Loc))) {2596 return Args[1];2597 }2598 2599 // (t1.get().*f)(t2, ..., tN) when f is a pointer to a member function of2600 // a class T and remove_cvref_t<decltype(t1)> is a specialization of2601 // reference_wrapper;2602 if (const auto *RD = ObjectT->getAsCXXRecordDecl()) {2603 if (RD->isInStdNamespace() &&2604 RD->getDeclName().getAsString() == "reference_wrapper") {2605 CXXScopeSpec SS;2606 IdentifierInfo *GetName = &S.Context.Idents.get("get");2607 UnqualifiedId GetID;2608 GetID.setIdentifier(GetName, Loc);2609 2610 ExprResult MemExpr = S.ActOnMemberAccessExpr(2611 S.getCurScope(), Args[1], Loc, tok::period, SS,2612 /*TemplateKWLoc=*/SourceLocation(), GetID, nullptr);2613 2614 if (MemExpr.isInvalid())2615 return ExprError();2616 2617 return S.ActOnCallExpr(S.getCurScope(), MemExpr.get(), Loc, {}, Loc);2618 }2619 }2620 2621 // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a2622 // class T and t1 does not satisfy the previous two items;2623 2624 return S.ActOnUnaryOp(S.getCurScope(), Loc, tok::star, Args[1]);2625 }();2626 2627 if (ObjectArg.isInvalid())2628 return ExprError();2629 2630 ExprResult BinOp = S.ActOnBinOp(S.getCurScope(), TheCall->getBeginLoc(),2631 tok::periodstar, ObjectArg.get(), Args[0]);2632 if (BinOp.isInvalid())2633 return ExprError();2634 2635 if (MPT->isMemberDataPointer())2636 return BinOp;2637 2638 auto *MemCall = new (S.Context)2639 ParenExpr(SourceLocation(), SourceLocation(), BinOp.get());2640 2641 return S.ActOnCallExpr(S.getCurScope(), MemCall, TheCall->getBeginLoc(),2642 Args.drop_front(2), TheCall->getRParenLoc());2643 }2644 return S.ActOnCallExpr(S.getCurScope(), Args.front(), TheCall->getBeginLoc(),2645 Args.drop_front(), TheCall->getRParenLoc());2646}2647 2648// Performs a similar job to Sema::UsualUnaryConversions, but without any2649// implicit promotion of integral/enumeration types.2650static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E) {2651 // First, convert to an r-value.2652 ExprResult Res = S.DefaultFunctionArrayLvalueConversion(E);2653 if (Res.isInvalid())2654 return ExprError();2655 2656 // Promote floating-point types.2657 return S.UsualUnaryFPConversions(Res.get());2658}2659 2660ExprResult2661Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,2662 CallExpr *TheCall) {2663 ExprResult TheCallResult(TheCall);2664 2665 // Find out if any arguments are required to be integer constant expressions.2666 unsigned ICEArguments = 0;2667 ASTContext::GetBuiltinTypeError Error;2668 Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);2669 if (Error != ASTContext::GE_None)2670 ICEArguments = 0; // Don't diagnose previously diagnosed errors.2671 2672 // If any arguments are required to be ICE's, check and diagnose.2673 for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {2674 // Skip arguments not required to be ICE's.2675 if ((ICEArguments & (1 << ArgNo)) == 0) continue;2676 2677 llvm::APSInt Result;2678 // If we don't have enough arguments, continue so we can issue better2679 // diagnostic in checkArgCount(...)2680 if (ArgNo < TheCall->getNumArgs() &&2681 BuiltinConstantArg(TheCall, ArgNo, Result))2682 return true;2683 ICEArguments &= ~(1 << ArgNo);2684 }2685 2686 FPOptions FPO;2687 switch (BuiltinID) {2688 case Builtin::BI__builtin_cpu_supports:2689 case Builtin::BI__builtin_cpu_is:2690 if (BuiltinCpu(*this, Context.getTargetInfo(), TheCall,2691 Context.getAuxTargetInfo(), BuiltinID))2692 return ExprError();2693 break;2694 case Builtin::BI__builtin_cpu_init:2695 if (!Context.getTargetInfo().supportsCpuInit()) {2696 Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)2697 << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());2698 return ExprError();2699 }2700 break;2701 case Builtin::BI__builtin___CFStringMakeConstantString:2702 // CFStringMakeConstantString is currently not implemented for GOFF (i.e.,2703 // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported2704 if (CheckBuiltinTargetNotInUnsupported(2705 *this, BuiltinID, TheCall,2706 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))2707 return ExprError();2708 assert(TheCall->getNumArgs() == 1 &&2709 "Wrong # arguments to builtin CFStringMakeConstantString");2710 if (ObjC().CheckObjCString(TheCall->getArg(0)))2711 return ExprError();2712 break;2713 case Builtin::BI__builtin_ms_va_start:2714 case Builtin::BI__builtin_stdarg_start:2715 case Builtin::BI__builtin_va_start:2716 case Builtin::BI__builtin_c23_va_start:2717 if (BuiltinVAStart(BuiltinID, TheCall))2718 return ExprError();2719 break;2720 case Builtin::BI__va_start: {2721 switch (Context.getTargetInfo().getTriple().getArch()) {2722 case llvm::Triple::aarch64:2723 case llvm::Triple::arm:2724 case llvm::Triple::thumb:2725 if (BuiltinVAStartARMMicrosoft(TheCall))2726 return ExprError();2727 break;2728 default:2729 if (BuiltinVAStart(BuiltinID, TheCall))2730 return ExprError();2731 break;2732 }2733 break;2734 }2735 2736 // The acquire, release, and no fence variants are ARM and AArch64 only.2737 case Builtin::BI_interlockedbittestandset_acq:2738 case Builtin::BI_interlockedbittestandset_rel:2739 case Builtin::BI_interlockedbittestandset_nf:2740 case Builtin::BI_interlockedbittestandreset_acq:2741 case Builtin::BI_interlockedbittestandreset_rel:2742 case Builtin::BI_interlockedbittestandreset_nf:2743 if (CheckBuiltinTargetInSupported(2744 *this, TheCall,2745 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))2746 return ExprError();2747 break;2748 2749 // The 64-bit bittest variants are x64, ARM, and AArch64 only.2750 case Builtin::BI_bittest64:2751 case Builtin::BI_bittestandcomplement64:2752 case Builtin::BI_bittestandreset64:2753 case Builtin::BI_bittestandset64:2754 case Builtin::BI_interlockedbittestandreset64:2755 case Builtin::BI_interlockedbittestandset64:2756 if (CheckBuiltinTargetInSupported(2757 *this, TheCall,2758 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,2759 llvm::Triple::aarch64, llvm::Triple::amdgcn}))2760 return ExprError();2761 break;2762 2763 // The 64-bit acquire, release, and no fence variants are AArch64 only.2764 case Builtin::BI_interlockedbittestandreset64_acq:2765 case Builtin::BI_interlockedbittestandreset64_rel:2766 case Builtin::BI_interlockedbittestandreset64_nf:2767 case Builtin::BI_interlockedbittestandset64_acq:2768 case Builtin::BI_interlockedbittestandset64_rel:2769 case Builtin::BI_interlockedbittestandset64_nf:2770 if (CheckBuiltinTargetInSupported(*this, TheCall, {llvm::Triple::aarch64}))2771 return ExprError();2772 break;2773 2774 case Builtin::BI__builtin_set_flt_rounds:2775 if (CheckBuiltinTargetInSupported(2776 *this, TheCall,2777 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,2778 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,2779 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,2780 llvm::Triple::ppc64le}))2781 return ExprError();2782 break;2783 2784 case Builtin::BI__builtin_isgreater:2785 case Builtin::BI__builtin_isgreaterequal:2786 case Builtin::BI__builtin_isless:2787 case Builtin::BI__builtin_islessequal:2788 case Builtin::BI__builtin_islessgreater:2789 case Builtin::BI__builtin_isunordered:2790 if (BuiltinUnorderedCompare(TheCall, BuiltinID))2791 return ExprError();2792 break;2793 case Builtin::BI__builtin_fpclassify:2794 if (BuiltinFPClassification(TheCall, 6, BuiltinID))2795 return ExprError();2796 break;2797 case Builtin::BI__builtin_isfpclass:2798 if (BuiltinFPClassification(TheCall, 2, BuiltinID))2799 return ExprError();2800 break;2801 case Builtin::BI__builtin_isfinite:2802 case Builtin::BI__builtin_isinf:2803 case Builtin::BI__builtin_isinf_sign:2804 case Builtin::BI__builtin_isnan:2805 case Builtin::BI__builtin_issignaling:2806 case Builtin::BI__builtin_isnormal:2807 case Builtin::BI__builtin_issubnormal:2808 case Builtin::BI__builtin_iszero:2809 case Builtin::BI__builtin_signbit:2810 case Builtin::BI__builtin_signbitf:2811 case Builtin::BI__builtin_signbitl:2812 if (BuiltinFPClassification(TheCall, 1, BuiltinID))2813 return ExprError();2814 break;2815 case Builtin::BI__builtin_shufflevector:2816 return BuiltinShuffleVector(TheCall);2817 // TheCall will be freed by the smart pointer here, but that's fine, since2818 // BuiltinShuffleVector guts it, but then doesn't release it.2819 case Builtin::BI__builtin_masked_load:2820 case Builtin::BI__builtin_masked_expand_load:2821 return BuiltinMaskedLoad(*this, TheCall);2822 case Builtin::BI__builtin_masked_store:2823 case Builtin::BI__builtin_masked_compress_store:2824 return BuiltinMaskedStore(*this, TheCall);2825 case Builtin::BI__builtin_masked_gather:2826 return BuiltinMaskedGather(*this, TheCall);2827 case Builtin::BI__builtin_masked_scatter:2828 return BuiltinMaskedScatter(*this, TheCall);2829 case Builtin::BI__builtin_invoke:2830 return BuiltinInvoke(*this, TheCall);2831 case Builtin::BI__builtin_prefetch:2832 if (BuiltinPrefetch(TheCall))2833 return ExprError();2834 break;2835 case Builtin::BI__builtin_alloca_with_align:2836 case Builtin::BI__builtin_alloca_with_align_uninitialized:2837 if (BuiltinAllocaWithAlign(TheCall))2838 return ExprError();2839 [[fallthrough]];2840 case Builtin::BI__builtin_alloca:2841 case Builtin::BI__builtin_alloca_uninitialized:2842 Diag(TheCall->getBeginLoc(), diag::warn_alloca)2843 << TheCall->getDirectCallee();2844 if (getLangOpts().OpenCL) {2845 builtinAllocaAddrSpace(*this, TheCall);2846 }2847 break;2848 case Builtin::BI__builtin_infer_alloc_token:2849 if (checkBuiltinInferAllocToken(*this, TheCall))2850 return ExprError();2851 break;2852 case Builtin::BI__arithmetic_fence:2853 if (BuiltinArithmeticFence(TheCall))2854 return ExprError();2855 break;2856 case Builtin::BI__assume:2857 case Builtin::BI__builtin_assume:2858 if (BuiltinAssume(TheCall))2859 return ExprError();2860 break;2861 case Builtin::BI__builtin_assume_aligned:2862 if (BuiltinAssumeAligned(TheCall))2863 return ExprError();2864 break;2865 case Builtin::BI__builtin_dynamic_object_size:2866 case Builtin::BI__builtin_object_size:2867 if (BuiltinConstantArgRange(TheCall, 1, 0, 3))2868 return ExprError();2869 break;2870 case Builtin::BI__builtin_longjmp:2871 if (BuiltinLongjmp(TheCall))2872 return ExprError();2873 break;2874 case Builtin::BI__builtin_setjmp:2875 if (BuiltinSetjmp(TheCall))2876 return ExprError();2877 break;2878 case Builtin::BI__builtin_classify_type:2879 if (checkArgCount(TheCall, 1))2880 return true;2881 TheCall->setType(Context.IntTy);2882 break;2883 case Builtin::BI__builtin_complex:2884 if (BuiltinComplex(TheCall))2885 return ExprError();2886 break;2887 case Builtin::BI__builtin_constant_p: {2888 if (checkArgCount(TheCall, 1))2889 return true;2890 ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));2891 if (Arg.isInvalid()) return true;2892 TheCall->setArg(0, Arg.get());2893 TheCall->setType(Context.IntTy);2894 break;2895 }2896 case Builtin::BI__builtin_launder:2897 return BuiltinLaunder(*this, TheCall);2898 case Builtin::BI__builtin_is_within_lifetime:2899 return BuiltinIsWithinLifetime(*this, TheCall);2900 case Builtin::BI__builtin_trivially_relocate:2901 return BuiltinTriviallyRelocate(*this, TheCall);2902 2903 case Builtin::BI__sync_fetch_and_add:2904 case Builtin::BI__sync_fetch_and_add_1:2905 case Builtin::BI__sync_fetch_and_add_2:2906 case Builtin::BI__sync_fetch_and_add_4:2907 case Builtin::BI__sync_fetch_and_add_8:2908 case Builtin::BI__sync_fetch_and_add_16:2909 case Builtin::BI__sync_fetch_and_sub:2910 case Builtin::BI__sync_fetch_and_sub_1:2911 case Builtin::BI__sync_fetch_and_sub_2:2912 case Builtin::BI__sync_fetch_and_sub_4:2913 case Builtin::BI__sync_fetch_and_sub_8:2914 case Builtin::BI__sync_fetch_and_sub_16:2915 case Builtin::BI__sync_fetch_and_or:2916 case Builtin::BI__sync_fetch_and_or_1:2917 case Builtin::BI__sync_fetch_and_or_2:2918 case Builtin::BI__sync_fetch_and_or_4:2919 case Builtin::BI__sync_fetch_and_or_8:2920 case Builtin::BI__sync_fetch_and_or_16:2921 case Builtin::BI__sync_fetch_and_and:2922 case Builtin::BI__sync_fetch_and_and_1:2923 case Builtin::BI__sync_fetch_and_and_2:2924 case Builtin::BI__sync_fetch_and_and_4:2925 case Builtin::BI__sync_fetch_and_and_8:2926 case Builtin::BI__sync_fetch_and_and_16:2927 case Builtin::BI__sync_fetch_and_xor:2928 case Builtin::BI__sync_fetch_and_xor_1:2929 case Builtin::BI__sync_fetch_and_xor_2:2930 case Builtin::BI__sync_fetch_and_xor_4:2931 case Builtin::BI__sync_fetch_and_xor_8:2932 case Builtin::BI__sync_fetch_and_xor_16:2933 case Builtin::BI__sync_fetch_and_nand:2934 case Builtin::BI__sync_fetch_and_nand_1:2935 case Builtin::BI__sync_fetch_and_nand_2:2936 case Builtin::BI__sync_fetch_and_nand_4:2937 case Builtin::BI__sync_fetch_and_nand_8:2938 case Builtin::BI__sync_fetch_and_nand_16:2939 case Builtin::BI__sync_add_and_fetch:2940 case Builtin::BI__sync_add_and_fetch_1:2941 case Builtin::BI__sync_add_and_fetch_2:2942 case Builtin::BI__sync_add_and_fetch_4:2943 case Builtin::BI__sync_add_and_fetch_8:2944 case Builtin::BI__sync_add_and_fetch_16:2945 case Builtin::BI__sync_sub_and_fetch:2946 case Builtin::BI__sync_sub_and_fetch_1:2947 case Builtin::BI__sync_sub_and_fetch_2:2948 case Builtin::BI__sync_sub_and_fetch_4:2949 case Builtin::BI__sync_sub_and_fetch_8:2950 case Builtin::BI__sync_sub_and_fetch_16:2951 case Builtin::BI__sync_and_and_fetch:2952 case Builtin::BI__sync_and_and_fetch_1:2953 case Builtin::BI__sync_and_and_fetch_2:2954 case Builtin::BI__sync_and_and_fetch_4:2955 case Builtin::BI__sync_and_and_fetch_8:2956 case Builtin::BI__sync_and_and_fetch_16:2957 case Builtin::BI__sync_or_and_fetch:2958 case Builtin::BI__sync_or_and_fetch_1:2959 case Builtin::BI__sync_or_and_fetch_2:2960 case Builtin::BI__sync_or_and_fetch_4:2961 case Builtin::BI__sync_or_and_fetch_8:2962 case Builtin::BI__sync_or_and_fetch_16:2963 case Builtin::BI__sync_xor_and_fetch:2964 case Builtin::BI__sync_xor_and_fetch_1:2965 case Builtin::BI__sync_xor_and_fetch_2:2966 case Builtin::BI__sync_xor_and_fetch_4:2967 case Builtin::BI__sync_xor_and_fetch_8:2968 case Builtin::BI__sync_xor_and_fetch_16:2969 case Builtin::BI__sync_nand_and_fetch:2970 case Builtin::BI__sync_nand_and_fetch_1:2971 case Builtin::BI__sync_nand_and_fetch_2:2972 case Builtin::BI__sync_nand_and_fetch_4:2973 case Builtin::BI__sync_nand_and_fetch_8:2974 case Builtin::BI__sync_nand_and_fetch_16:2975 case Builtin::BI__sync_val_compare_and_swap:2976 case Builtin::BI__sync_val_compare_and_swap_1:2977 case Builtin::BI__sync_val_compare_and_swap_2:2978 case Builtin::BI__sync_val_compare_and_swap_4:2979 case Builtin::BI__sync_val_compare_and_swap_8:2980 case Builtin::BI__sync_val_compare_and_swap_16:2981 case Builtin::BI__sync_bool_compare_and_swap:2982 case Builtin::BI__sync_bool_compare_and_swap_1:2983 case Builtin::BI__sync_bool_compare_and_swap_2:2984 case Builtin::BI__sync_bool_compare_and_swap_4:2985 case Builtin::BI__sync_bool_compare_and_swap_8:2986 case Builtin::BI__sync_bool_compare_and_swap_16:2987 case Builtin::BI__sync_lock_test_and_set:2988 case Builtin::BI__sync_lock_test_and_set_1:2989 case Builtin::BI__sync_lock_test_and_set_2:2990 case Builtin::BI__sync_lock_test_and_set_4:2991 case Builtin::BI__sync_lock_test_and_set_8:2992 case Builtin::BI__sync_lock_test_and_set_16:2993 case Builtin::BI__sync_lock_release:2994 case Builtin::BI__sync_lock_release_1:2995 case Builtin::BI__sync_lock_release_2:2996 case Builtin::BI__sync_lock_release_4:2997 case Builtin::BI__sync_lock_release_8:2998 case Builtin::BI__sync_lock_release_16:2999 case Builtin::BI__sync_swap:3000 case Builtin::BI__sync_swap_1:3001 case Builtin::BI__sync_swap_2:3002 case Builtin::BI__sync_swap_4:3003 case Builtin::BI__sync_swap_8:3004 case Builtin::BI__sync_swap_16:3005 return BuiltinAtomicOverloaded(TheCallResult);3006 case Builtin::BI__sync_synchronize:3007 Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst)3008 << TheCall->getCallee()->getSourceRange();3009 break;3010 case Builtin::BI__builtin_nontemporal_load:3011 case Builtin::BI__builtin_nontemporal_store:3012 return BuiltinNontemporalOverloaded(TheCallResult);3013 case Builtin::BI__builtin_memcpy_inline: {3014 clang::Expr *SizeOp = TheCall->getArg(2);3015 // We warn about copying to or from `nullptr` pointers when `size` is3016 // greater than 0. When `size` is value dependent we cannot evaluate its3017 // value so we bail out.3018 if (SizeOp->isValueDependent())3019 break;3020 if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) {3021 CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());3022 CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());3023 }3024 break;3025 }3026 case Builtin::BI__builtin_memset_inline: {3027 clang::Expr *SizeOp = TheCall->getArg(2);3028 // We warn about filling to `nullptr` pointers when `size` is greater than3029 // 0. When `size` is value dependent we cannot evaluate its value so we bail3030 // out.3031 if (SizeOp->isValueDependent())3032 break;3033 if (!SizeOp->EvaluateKnownConstInt(Context).isZero())3034 CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());3035 break;3036 }3037#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \3038 case Builtin::BI##ID: \3039 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);3040#include "clang/Basic/Builtins.inc"3041 case Builtin::BI__annotation:3042 if (BuiltinMSVCAnnotation(*this, TheCall))3043 return ExprError();3044 break;3045 case Builtin::BI__builtin_annotation:3046 if (BuiltinAnnotation(*this, TheCall))3047 return ExprError();3048 break;3049 case Builtin::BI__builtin_addressof:3050 if (BuiltinAddressof(*this, TheCall))3051 return ExprError();3052 break;3053 case Builtin::BI__builtin_function_start:3054 if (BuiltinFunctionStart(*this, TheCall))3055 return ExprError();3056 break;3057 case Builtin::BI__builtin_is_aligned:3058 case Builtin::BI__builtin_align_up:3059 case Builtin::BI__builtin_align_down:3060 if (BuiltinAlignment(*this, TheCall, BuiltinID))3061 return ExprError();3062 break;3063 case Builtin::BI__builtin_add_overflow:3064 case Builtin::BI__builtin_sub_overflow:3065 case Builtin::BI__builtin_mul_overflow:3066 if (BuiltinOverflow(*this, TheCall, BuiltinID))3067 return ExprError();3068 break;3069 case Builtin::BI__builtin_operator_new:3070 case Builtin::BI__builtin_operator_delete: {3071 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;3072 ExprResult Res =3073 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);3074 return Res;3075 }3076 case Builtin::BI__builtin_dump_struct:3077 return BuiltinDumpStruct(*this, TheCall);3078 case Builtin::BI__builtin_expect_with_probability: {3079 // We first want to ensure we are called with 3 arguments3080 if (checkArgCount(TheCall, 3))3081 return ExprError();3082 // then check probability is constant float in range [0.0, 1.0]3083 const Expr *ProbArg = TheCall->getArg(2);3084 SmallVector<PartialDiagnosticAt, 8> Notes;3085 Expr::EvalResult Eval;3086 Eval.Diag = &Notes;3087 if ((!ProbArg->EvaluateAsConstantExpr(Eval, Context)) ||3088 !Eval.Val.isFloat()) {3089 Diag(ProbArg->getBeginLoc(), diag::err_probability_not_constant_float)3090 << ProbArg->getSourceRange();3091 for (const PartialDiagnosticAt &PDiag : Notes)3092 Diag(PDiag.first, PDiag.second);3093 return ExprError();3094 }3095 llvm::APFloat Probability = Eval.Val.getFloat();3096 bool LoseInfo = false;3097 Probability.convert(llvm::APFloat::IEEEdouble(),3098 llvm::RoundingMode::Dynamic, &LoseInfo);3099 if (!(Probability >= llvm::APFloat(0.0) &&3100 Probability <= llvm::APFloat(1.0))) {3101 Diag(ProbArg->getBeginLoc(), diag::err_probability_out_of_range)3102 << ProbArg->getSourceRange();3103 return ExprError();3104 }3105 break;3106 }3107 case Builtin::BI__builtin_preserve_access_index:3108 if (BuiltinPreserveAI(*this, TheCall))3109 return ExprError();3110 break;3111 case Builtin::BI__builtin_call_with_static_chain:3112 if (BuiltinCallWithStaticChain(*this, TheCall))3113 return ExprError();3114 break;3115 case Builtin::BI__exception_code:3116 case Builtin::BI_exception_code:3117 if (BuiltinSEHScopeCheck(*this, TheCall, Scope::SEHExceptScope,3118 diag::err_seh___except_block))3119 return ExprError();3120 break;3121 case Builtin::BI__exception_info:3122 case Builtin::BI_exception_info:3123 if (BuiltinSEHScopeCheck(*this, TheCall, Scope::SEHFilterScope,3124 diag::err_seh___except_filter))3125 return ExprError();3126 break;3127 case Builtin::BI__GetExceptionInfo:3128 if (checkArgCount(TheCall, 1))3129 return ExprError();3130 3131 if (CheckCXXThrowOperand(3132 TheCall->getBeginLoc(),3133 Context.getExceptionObjectType(FDecl->getParamDecl(0)->getType()),3134 TheCall))3135 return ExprError();3136 3137 TheCall->setType(Context.VoidPtrTy);3138 break;3139 case Builtin::BIaddressof:3140 case Builtin::BI__addressof:3141 case Builtin::BIforward:3142 case Builtin::BIforward_like:3143 case Builtin::BImove:3144 case Builtin::BImove_if_noexcept:3145 case Builtin::BIas_const: {3146 // These are all expected to be of the form3147 // T &/&&/* f(U &/&&)3148 // where T and U only differ in qualification.3149 if (checkArgCount(TheCall, 1))3150 return ExprError();3151 QualType Param = FDecl->getParamDecl(0)->getType();3152 QualType Result = FDecl->getReturnType();3153 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||3154 BuiltinID == Builtin::BI__addressof;3155 if (!(Param->isReferenceType() &&3156 (ReturnsPointer ? Result->isAnyPointerType()3157 : Result->isReferenceType()) &&3158 Context.hasSameUnqualifiedType(Param->getPointeeType(),3159 Result->getPointeeType()))) {3160 Diag(TheCall->getBeginLoc(), diag::err_builtin_move_forward_unsupported)3161 << FDecl;3162 return ExprError();3163 }3164 break;3165 }3166 case Builtin::BI__builtin_ptrauth_strip:3167 return PointerAuthStrip(*this, TheCall);3168 case Builtin::BI__builtin_ptrauth_blend_discriminator:3169 return PointerAuthBlendDiscriminator(*this, TheCall);3170 case Builtin::BI__builtin_ptrauth_sign_constant:3171 return PointerAuthSignOrAuth(*this, TheCall, PAO_Sign,3172 /*RequireConstant=*/true);3173 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:3174 return PointerAuthSignOrAuth(*this, TheCall, PAO_Sign,3175 /*RequireConstant=*/false);3176 case Builtin::BI__builtin_ptrauth_auth:3177 return PointerAuthSignOrAuth(*this, TheCall, PAO_Auth,3178 /*RequireConstant=*/false);3179 case Builtin::BI__builtin_ptrauth_sign_generic_data:3180 return PointerAuthSignGenericData(*this, TheCall);3181 case Builtin::BI__builtin_ptrauth_auth_and_resign:3182 return PointerAuthAuthAndResign(*this, TheCall);3183 case Builtin::BI__builtin_ptrauth_string_discriminator:3184 return PointerAuthStringDiscriminator(*this, TheCall);3185 3186 case Builtin::BI__builtin_get_vtable_pointer:3187 return GetVTablePointer(*this, TheCall);3188 3189 // OpenCL v2.0, s6.13.16 - Pipe functions3190 case Builtin::BIread_pipe:3191 case Builtin::BIwrite_pipe:3192 // Since those two functions are declared with var args, we need a semantic3193 // check for the argument.3194 if (OpenCL().checkBuiltinRWPipe(TheCall))3195 return ExprError();3196 break;3197 case Builtin::BIreserve_read_pipe:3198 case Builtin::BIreserve_write_pipe:3199 case Builtin::BIwork_group_reserve_read_pipe:3200 case Builtin::BIwork_group_reserve_write_pipe:3201 if (OpenCL().checkBuiltinReserveRWPipe(TheCall))3202 return ExprError();3203 break;3204 case Builtin::BIsub_group_reserve_read_pipe:3205 case Builtin::BIsub_group_reserve_write_pipe:3206 if (OpenCL().checkSubgroupExt(TheCall) ||3207 OpenCL().checkBuiltinReserveRWPipe(TheCall))3208 return ExprError();3209 break;3210 case Builtin::BIcommit_read_pipe:3211 case Builtin::BIcommit_write_pipe:3212 case Builtin::BIwork_group_commit_read_pipe:3213 case Builtin::BIwork_group_commit_write_pipe:3214 if (OpenCL().checkBuiltinCommitRWPipe(TheCall))3215 return ExprError();3216 break;3217 case Builtin::BIsub_group_commit_read_pipe:3218 case Builtin::BIsub_group_commit_write_pipe:3219 if (OpenCL().checkSubgroupExt(TheCall) ||3220 OpenCL().checkBuiltinCommitRWPipe(TheCall))3221 return ExprError();3222 break;3223 case Builtin::BIget_pipe_num_packets:3224 case Builtin::BIget_pipe_max_packets:3225 if (OpenCL().checkBuiltinPipePackets(TheCall))3226 return ExprError();3227 break;3228 case Builtin::BIto_global:3229 case Builtin::BIto_local:3230 case Builtin::BIto_private:3231 if (OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))3232 return ExprError();3233 break;3234 // OpenCL v2.0, s6.13.17 - Enqueue kernel functions.3235 case Builtin::BIenqueue_kernel:3236 if (OpenCL().checkBuiltinEnqueueKernel(TheCall))3237 return ExprError();3238 break;3239 case Builtin::BIget_kernel_work_group_size:3240 case Builtin::BIget_kernel_preferred_work_group_size_multiple:3241 if (OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))3242 return ExprError();3243 break;3244 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:3245 case Builtin::BIget_kernel_sub_group_count_for_ndrange:3246 if (OpenCL().checkBuiltinNDRangeAndBlock(TheCall))3247 return ExprError();3248 break;3249 case Builtin::BI__builtin_os_log_format:3250 Cleanup.setExprNeedsCleanups(true);3251 [[fallthrough]];3252 case Builtin::BI__builtin_os_log_format_buffer_size:3253 if (BuiltinOSLogFormat(TheCall))3254 return ExprError();3255 break;3256 case Builtin::BI__builtin_frame_address:3257 case Builtin::BI__builtin_return_address: {3258 if (BuiltinConstantArgRange(TheCall, 0, 0, 0xFFFF))3259 return ExprError();3260 3261 // -Wframe-address warning if non-zero passed to builtin3262 // return/frame address.3263 Expr::EvalResult Result;3264 if (!TheCall->getArg(0)->isValueDependent() &&3265 TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&3266 Result.Val.getInt() != 0)3267 Diag(TheCall->getBeginLoc(), diag::warn_frame_address)3268 << ((BuiltinID == Builtin::BI__builtin_return_address)3269 ? "__builtin_return_address"3270 : "__builtin_frame_address")3271 << TheCall->getSourceRange();3272 break;3273 }3274 3275 case Builtin::BI__builtin_nondeterministic_value: {3276 if (BuiltinNonDeterministicValue(TheCall))3277 return ExprError();3278 break;3279 }3280 3281 // __builtin_elementwise_abs restricts the element type to signed integers or3282 // floating point types only.3283 case Builtin::BI__builtin_elementwise_abs:3284 if (PrepareBuiltinElementwiseMathOneArgCall(3285 TheCall, EltwiseBuiltinArgTyRestriction::SignedIntOrFloatTy))3286 return ExprError();3287 break;3288 3289 // These builtins restrict the element type to floating point3290 // types only.3291 case Builtin::BI__builtin_elementwise_acos:3292 case Builtin::BI__builtin_elementwise_asin:3293 case Builtin::BI__builtin_elementwise_atan:3294 case Builtin::BI__builtin_elementwise_ceil:3295 case Builtin::BI__builtin_elementwise_cos:3296 case Builtin::BI__builtin_elementwise_cosh:3297 case Builtin::BI__builtin_elementwise_exp:3298 case Builtin::BI__builtin_elementwise_exp2:3299 case Builtin::BI__builtin_elementwise_exp10:3300 case Builtin::BI__builtin_elementwise_floor:3301 case Builtin::BI__builtin_elementwise_log:3302 case Builtin::BI__builtin_elementwise_log2:3303 case Builtin::BI__builtin_elementwise_log10:3304 case Builtin::BI__builtin_elementwise_roundeven:3305 case Builtin::BI__builtin_elementwise_round:3306 case Builtin::BI__builtin_elementwise_rint:3307 case Builtin::BI__builtin_elementwise_nearbyint:3308 case Builtin::BI__builtin_elementwise_sin:3309 case Builtin::BI__builtin_elementwise_sinh:3310 case Builtin::BI__builtin_elementwise_sqrt:3311 case Builtin::BI__builtin_elementwise_tan:3312 case Builtin::BI__builtin_elementwise_tanh:3313 case Builtin::BI__builtin_elementwise_trunc:3314 case Builtin::BI__builtin_elementwise_canonicalize:3315 if (PrepareBuiltinElementwiseMathOneArgCall(3316 TheCall, EltwiseBuiltinArgTyRestriction::FloatTy))3317 return ExprError();3318 break;3319 case Builtin::BI__builtin_elementwise_fma:3320 if (BuiltinElementwiseTernaryMath(TheCall))3321 return ExprError();3322 break;3323 3324 case Builtin::BI__builtin_elementwise_ldexp: {3325 if (checkArgCount(TheCall, 2))3326 return ExprError();3327 3328 ExprResult A = BuiltinVectorMathConversions(*this, TheCall->getArg(0));3329 if (A.isInvalid())3330 return ExprError();3331 QualType TyA = A.get()->getType();3332 if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA,3333 EltwiseBuiltinArgTyRestriction::FloatTy, 1))3334 return ExprError();3335 3336 ExprResult Exp = UsualUnaryConversions(TheCall->getArg(1));3337 if (Exp.isInvalid())3338 return ExprError();3339 QualType TyExp = Exp.get()->getType();3340 if (checkMathBuiltinElementType(*this, Exp.get()->getBeginLoc(), TyExp,3341 EltwiseBuiltinArgTyRestriction::IntegerTy,3342 2))3343 return ExprError();3344 3345 // Check the two arguments are either scalars or vectors of equal length.3346 const auto *Vec0 = TyA->getAs<VectorType>();3347 const auto *Vec1 = TyExp->getAs<VectorType>();3348 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;3349 unsigned Arg1Length = Vec1 ? Vec1->getNumElements() : 0;3350 if (Arg0Length != Arg1Length) {3351 Diag(Exp.get()->getBeginLoc(),3352 diag::err_typecheck_vector_lengths_not_equal)3353 << TyA << TyExp << A.get()->getSourceRange()3354 << Exp.get()->getSourceRange();3355 return ExprError();3356 }3357 3358 TheCall->setArg(0, A.get());3359 TheCall->setArg(1, Exp.get());3360 TheCall->setType(TyA);3361 break;3362 }3363 3364 // These builtins restrict the element type to floating point3365 // types only, and take in two arguments.3366 case Builtin::BI__builtin_elementwise_minnum:3367 case Builtin::BI__builtin_elementwise_maxnum:3368 case Builtin::BI__builtin_elementwise_minimum:3369 case Builtin::BI__builtin_elementwise_maximum:3370 case Builtin::BI__builtin_elementwise_minimumnum:3371 case Builtin::BI__builtin_elementwise_maximumnum:3372 case Builtin::BI__builtin_elementwise_atan2:3373 case Builtin::BI__builtin_elementwise_fmod:3374 case Builtin::BI__builtin_elementwise_pow:3375 if (BuiltinElementwiseMath(TheCall,3376 EltwiseBuiltinArgTyRestriction::FloatTy))3377 return ExprError();3378 break;3379 // These builtins restrict the element type to integer3380 // types only.3381 case Builtin::BI__builtin_elementwise_add_sat:3382 case Builtin::BI__builtin_elementwise_sub_sat:3383 if (BuiltinElementwiseMath(TheCall,3384 EltwiseBuiltinArgTyRestriction::IntegerTy))3385 return ExprError();3386 break;3387 case Builtin::BI__builtin_elementwise_fshl:3388 case Builtin::BI__builtin_elementwise_fshr:3389 if (BuiltinElementwiseTernaryMath(3390 TheCall, EltwiseBuiltinArgTyRestriction::IntegerTy))3391 return ExprError();3392 break;3393 case Builtin::BI__builtin_elementwise_min:3394 case Builtin::BI__builtin_elementwise_max:3395 if (BuiltinElementwiseMath(TheCall))3396 return ExprError();3397 break;3398 case Builtin::BI__builtin_elementwise_popcount:3399 case Builtin::BI__builtin_elementwise_bitreverse:3400 if (PrepareBuiltinElementwiseMathOneArgCall(3401 TheCall, EltwiseBuiltinArgTyRestriction::IntegerTy))3402 return ExprError();3403 break;3404 case Builtin::BI__builtin_elementwise_copysign: {3405 if (checkArgCount(TheCall, 2))3406 return ExprError();3407 3408 ExprResult Magnitude = UsualUnaryConversions(TheCall->getArg(0));3409 ExprResult Sign = UsualUnaryConversions(TheCall->getArg(1));3410 if (Magnitude.isInvalid() || Sign.isInvalid())3411 return ExprError();3412 3413 QualType MagnitudeTy = Magnitude.get()->getType();3414 QualType SignTy = Sign.get()->getType();3415 if (checkMathBuiltinElementType(3416 *this, TheCall->getArg(0)->getBeginLoc(), MagnitudeTy,3417 EltwiseBuiltinArgTyRestriction::FloatTy, 1) ||3418 checkMathBuiltinElementType(3419 *this, TheCall->getArg(1)->getBeginLoc(), SignTy,3420 EltwiseBuiltinArgTyRestriction::FloatTy, 2)) {3421 return ExprError();3422 }3423 3424 if (MagnitudeTy.getCanonicalType() != SignTy.getCanonicalType()) {3425 return Diag(Sign.get()->getBeginLoc(),3426 diag::err_typecheck_call_different_arg_types)3427 << MagnitudeTy << SignTy;3428 }3429 3430 TheCall->setArg(0, Magnitude.get());3431 TheCall->setArg(1, Sign.get());3432 TheCall->setType(Magnitude.get()->getType());3433 break;3434 }3435 case Builtin::BI__builtin_elementwise_clzg:3436 case Builtin::BI__builtin_elementwise_ctzg:3437 // These builtins can be unary or binary. Note for empty calls we call the3438 // unary checker in order to not emit an error that says the function3439 // expects 2 arguments, which would be misleading.3440 if (TheCall->getNumArgs() <= 1) {3441 if (PrepareBuiltinElementwiseMathOneArgCall(3442 TheCall, EltwiseBuiltinArgTyRestriction::IntegerTy))3443 return ExprError();3444 } else if (BuiltinElementwiseMath(3445 TheCall, EltwiseBuiltinArgTyRestriction::IntegerTy))3446 return ExprError();3447 break;3448 case Builtin::BI__builtin_reduce_max:3449 case Builtin::BI__builtin_reduce_min: {3450 if (PrepareBuiltinReduceMathOneArgCall(TheCall))3451 return ExprError();3452 3453 const Expr *Arg = TheCall->getArg(0);3454 const auto *TyA = Arg->getType()->getAs<VectorType>();3455 3456 QualType ElTy;3457 if (TyA)3458 ElTy = TyA->getElementType();3459 else if (Arg->getType()->isSizelessVectorType())3460 ElTy = Arg->getType()->getSizelessVectorEltType(Context);3461 3462 if (ElTy.isNull()) {3463 Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)3464 << 1 << /* vector ty */ 2 << /* no int */ 0 << /* no fp */ 03465 << Arg->getType();3466 return ExprError();3467 }3468 3469 TheCall->setType(ElTy);3470 break;3471 }3472 case Builtin::BI__builtin_reduce_maximum:3473 case Builtin::BI__builtin_reduce_minimum: {3474 if (PrepareBuiltinReduceMathOneArgCall(TheCall))3475 return ExprError();3476 3477 const Expr *Arg = TheCall->getArg(0);3478 const auto *TyA = Arg->getType()->getAs<VectorType>();3479 3480 QualType ElTy;3481 if (TyA)3482 ElTy = TyA->getElementType();3483 else if (Arg->getType()->isSizelessVectorType())3484 ElTy = Arg->getType()->getSizelessVectorEltType(Context);3485 3486 if (ElTy.isNull() || !ElTy->isFloatingType()) {3487 Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)3488 << 1 << /* vector of */ 4 << /* no int */ 0 << /* fp */ 13489 << Arg->getType();3490 return ExprError();3491 }3492 3493 TheCall->setType(ElTy);3494 break;3495 }3496 3497 // These builtins support vectors of integers only.3498 // TODO: ADD/MUL should support floating-point types.3499 case Builtin::BI__builtin_reduce_add:3500 case Builtin::BI__builtin_reduce_mul:3501 case Builtin::BI__builtin_reduce_xor:3502 case Builtin::BI__builtin_reduce_or:3503 case Builtin::BI__builtin_reduce_and: {3504 if (PrepareBuiltinReduceMathOneArgCall(TheCall))3505 return ExprError();3506 3507 const Expr *Arg = TheCall->getArg(0);3508 const auto *TyA = Arg->getType()->getAs<VectorType>();3509 3510 QualType ElTy;3511 if (TyA)3512 ElTy = TyA->getElementType();3513 else if (Arg->getType()->isSizelessVectorType())3514 ElTy = Arg->getType()->getSizelessVectorEltType(Context);3515 3516 if (ElTy.isNull() || !ElTy->isIntegerType()) {3517 Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)3518 << 1 << /* vector of */ 4 << /* int */ 1 << /* no fp */ 03519 << Arg->getType();3520 return ExprError();3521 }3522 3523 TheCall->setType(ElTy);3524 break;3525 }3526 3527 case Builtin::BI__builtin_matrix_transpose:3528 return BuiltinMatrixTranspose(TheCall, TheCallResult);3529 3530 case Builtin::BI__builtin_matrix_column_major_load:3531 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);3532 3533 case Builtin::BI__builtin_matrix_column_major_store:3534 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);3535 3536 case Builtin::BI__builtin_verbose_trap:3537 if (!checkBuiltinVerboseTrap(TheCall, *this))3538 return ExprError();3539 break;3540 3541 case Builtin::BI__builtin_get_device_side_mangled_name: {3542 auto Check = [](CallExpr *TheCall) {3543 if (TheCall->getNumArgs() != 1)3544 return false;3545 auto *DRE = dyn_cast<DeclRefExpr>(TheCall->getArg(0)->IgnoreImpCasts());3546 if (!DRE)3547 return false;3548 auto *D = DRE->getDecl();3549 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D))3550 return false;3551 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||3552 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();3553 };3554 if (!Check(TheCall)) {3555 Diag(TheCall->getBeginLoc(),3556 diag::err_hip_invalid_args_builtin_mangled_name);3557 return ExprError();3558 }3559 break;3560 }3561 case Builtin::BI__builtin_bswapg:3562 if (BuiltinBswapg(*this, TheCall))3563 return ExprError();3564 break;3565 case Builtin::BI__builtin_popcountg:3566 if (BuiltinPopcountg(*this, TheCall))3567 return ExprError();3568 break;3569 case Builtin::BI__builtin_clzg:3570 case Builtin::BI__builtin_ctzg:3571 if (BuiltinCountZeroBitsGeneric(*this, TheCall))3572 return ExprError();3573 break;3574 3575 case Builtin::BI__builtin_allow_runtime_check: {3576 Expr *Arg = TheCall->getArg(0);3577 // Check if the argument is a string literal.3578 if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) {3579 Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)3580 << Arg->getSourceRange();3581 return ExprError();3582 }3583 break;3584 }3585 case Builtin::BI__builtin_counted_by_ref:3586 if (BuiltinCountedByRef(TheCall))3587 return ExprError();3588 break;3589 }3590 3591 if (getLangOpts().HLSL && HLSL().CheckBuiltinFunctionCall(BuiltinID, TheCall))3592 return ExprError();3593 3594 // Since the target specific builtins for each arch overlap, only check those3595 // of the arch we are compiling for.3596 if (Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {3597 if (Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {3598 assert(Context.getAuxTargetInfo() &&3599 "Aux Target Builtin, but not an aux target?");3600 3601 if (CheckTSBuiltinFunctionCall(3602 *Context.getAuxTargetInfo(),3603 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))3604 return ExprError();3605 } else {3606 if (CheckTSBuiltinFunctionCall(Context.getTargetInfo(), BuiltinID,3607 TheCall))3608 return ExprError();3609 }3610 }3611 3612 return TheCallResult;3613}3614 3615bool Sema::ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum) {3616 llvm::APSInt Result;3617 // We can't check the value of a dependent argument.3618 Expr *Arg = TheCall->getArg(ArgNum);3619 if (Arg->isTypeDependent() || Arg->isValueDependent())3620 return false;3621 3622 // Check constant-ness first.3623 if (BuiltinConstantArg(TheCall, ArgNum, Result))3624 return true;3625 3626 // Check contiguous run of 1s, 0xFF0000FF is also a run of 1s.3627 if (Result.isShiftedMask() || (~Result).isShiftedMask())3628 return false;3629 3630 return Diag(TheCall->getBeginLoc(),3631 diag::err_argument_not_contiguous_bit_field)3632 << ArgNum << Arg->getSourceRange();3633}3634 3635bool Sema::getFormatStringInfo(const Decl *D, unsigned FormatIdx,3636 unsigned FirstArg, FormatStringInfo *FSI) {3637 bool HasImplicitThisParam = hasImplicitObjectParameter(D);3638 bool IsVariadic = false;3639 if (const FunctionType *FnTy = D->getFunctionType())3640 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();3641 else if (const auto *BD = dyn_cast<BlockDecl>(D))3642 IsVariadic = BD->isVariadic();3643 else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D))3644 IsVariadic = OMD->isVariadic();3645 3646 return getFormatStringInfo(FormatIdx, FirstArg, HasImplicitThisParam,3647 IsVariadic, FSI);3648}3649 3650bool Sema::getFormatStringInfo(unsigned FormatIdx, unsigned FirstArg,3651 bool HasImplicitThisParam, bool IsVariadic,3652 FormatStringInfo *FSI) {3653 if (FirstArg == 0)3654 FSI->ArgPassingKind = FAPK_VAList;3655 else if (IsVariadic)3656 FSI->ArgPassingKind = FAPK_Variadic;3657 else3658 FSI->ArgPassingKind = FAPK_Fixed;3659 FSI->FormatIdx = FormatIdx - 1;3660 FSI->FirstDataArg = FSI->ArgPassingKind == FAPK_VAList ? 0 : FirstArg - 1;3661 3662 // The way the format attribute works in GCC, the implicit this argument3663 // of member functions is counted. However, it doesn't appear in our own3664 // lists, so decrement format_idx in that case.3665 if (HasImplicitThisParam) {3666 if(FSI->FormatIdx == 0)3667 return false;3668 --FSI->FormatIdx;3669 if (FSI->FirstDataArg != 0)3670 --FSI->FirstDataArg;3671 }3672 return true;3673}3674 3675/// Checks if a the given expression evaluates to null.3676///3677/// Returns true if the value evaluates to null.3678static bool CheckNonNullExpr(Sema &S, const Expr *Expr) {3679 // Treat (smart) pointers constructed from nullptr as null, whether we can3680 // const-evaluate them or not.3681 // This must happen first: the smart pointer expr might have _Nonnull type!3682 if (isa<CXXNullPtrLiteralExpr>(3683 IgnoreExprNodes(Expr, IgnoreImplicitAsWrittenSingleStep,3684 IgnoreElidableImplicitConstructorSingleStep)))3685 return true;3686 3687 // If the expression has non-null type, it doesn't evaluate to null.3688 if (auto nullability = Expr->IgnoreImplicit()->getType()->getNullability()) {3689 if (*nullability == NullabilityKind::NonNull)3690 return false;3691 }3692 3693 // As a special case, transparent unions initialized with zero are3694 // considered null for the purposes of the nonnull attribute.3695 if (const RecordType *UT = Expr->getType()->getAsUnionType();3696 UT &&3697 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {3698 if (const auto *CLE = dyn_cast<CompoundLiteralExpr>(Expr))3699 if (const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))3700 Expr = ILE->getInit(0);3701 }3702 3703 bool Result;3704 return (!Expr->isValueDependent() &&3705 Expr->EvaluateAsBooleanCondition(Result, S.Context) &&3706 !Result);3707}3708 3709static void CheckNonNullArgument(Sema &S,3710 const Expr *ArgExpr,3711 SourceLocation CallSiteLoc) {3712 if (CheckNonNullExpr(S, ArgExpr))3713 S.DiagRuntimeBehavior(CallSiteLoc, ArgExpr,3714 S.PDiag(diag::warn_null_arg)3715 << ArgExpr->getSourceRange());3716}3717 3718/// Determine whether the given type has a non-null nullability annotation.3719static bool isNonNullType(QualType type) {3720 if (auto nullability = type->getNullability())3721 return *nullability == NullabilityKind::NonNull;3722 3723 return false;3724}3725 3726static void CheckNonNullArguments(Sema &S,3727 const NamedDecl *FDecl,3728 const FunctionProtoType *Proto,3729 ArrayRef<const Expr *> Args,3730 SourceLocation CallSiteLoc) {3731 assert((FDecl || Proto) && "Need a function declaration or prototype");3732 3733 // Already checked by constant evaluator.3734 if (S.isConstantEvaluatedContext())3735 return;3736 // Check the attributes attached to the method/function itself.3737 llvm::SmallBitVector NonNullArgs;3738 if (FDecl) {3739 // Handle the nonnull attribute on the function/method declaration itself.3740 for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) {3741 if (!NonNull->args_size()) {3742 // Easy case: all pointer arguments are nonnull.3743 for (const auto *Arg : Args)3744 if (S.isValidPointerAttrType(Arg->getType()))3745 CheckNonNullArgument(S, Arg, CallSiteLoc);3746 return;3747 }3748 3749 for (const ParamIdx &Idx : NonNull->args()) {3750 unsigned IdxAST = Idx.getASTIndex();3751 if (IdxAST >= Args.size())3752 continue;3753 if (NonNullArgs.empty())3754 NonNullArgs.resize(Args.size());3755 NonNullArgs.set(IdxAST);3756 }3757 }3758 }3759 3760 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {3761 // Handle the nonnull attribute on the parameters of the3762 // function/method.3763 ArrayRef<ParmVarDecl*> parms;3764 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))3765 parms = FD->parameters();3766 else3767 parms = cast<ObjCMethodDecl>(FDecl)->parameters();3768 3769 unsigned ParamIndex = 0;3770 for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();3771 I != E; ++I, ++ParamIndex) {3772 const ParmVarDecl *PVD = *I;3773 if (PVD->hasAttr<NonNullAttr>() || isNonNullType(PVD->getType())) {3774 if (NonNullArgs.empty())3775 NonNullArgs.resize(Args.size());3776 3777 NonNullArgs.set(ParamIndex);3778 }3779 }3780 } else {3781 // If we have a non-function, non-method declaration but no3782 // function prototype, try to dig out the function prototype.3783 if (!Proto) {3784 if (const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {3785 QualType type = VD->getType().getNonReferenceType();3786 if (auto pointerType = type->getAs<PointerType>())3787 type = pointerType->getPointeeType();3788 else if (auto blockType = type->getAs<BlockPointerType>())3789 type = blockType->getPointeeType();3790 // FIXME: data member pointers?3791 3792 // Dig out the function prototype, if there is one.3793 Proto = type->getAs<FunctionProtoType>();3794 }3795 }3796 3797 // Fill in non-null argument information from the nullability3798 // information on the parameter types (if we have them).3799 if (Proto) {3800 unsigned Index = 0;3801 for (auto paramType : Proto->getParamTypes()) {3802 if (isNonNullType(paramType)) {3803 if (NonNullArgs.empty())3804 NonNullArgs.resize(Args.size());3805 3806 NonNullArgs.set(Index);3807 }3808 3809 ++Index;3810 }3811 }3812 }3813 3814 // Check for non-null arguments.3815 for (unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();3816 ArgIndex != ArgIndexEnd; ++ArgIndex) {3817 if (NonNullArgs[ArgIndex])3818 CheckNonNullArgument(S, Args[ArgIndex], Args[ArgIndex]->getExprLoc());3819 }3820}3821 3822void Sema::CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl,3823 StringRef ParamName, QualType ArgTy,3824 QualType ParamTy) {3825 3826 // If a function accepts a pointer or reference type3827 if (!ParamTy->isPointerType() && !ParamTy->isReferenceType())3828 return;3829 3830 // If the parameter is a pointer type, get the pointee type for the3831 // argument too. If the parameter is a reference type, don't try to get3832 // the pointee type for the argument.3833 if (ParamTy->isPointerType())3834 ArgTy = ArgTy->getPointeeType();3835 3836 // Remove reference or pointer3837 ParamTy = ParamTy->getPointeeType();3838 3839 // Find expected alignment, and the actual alignment of the passed object.3840 // getTypeAlignInChars requires complete types3841 if (ArgTy.isNull() || ParamTy->isDependentType() ||3842 ParamTy->isIncompleteType() || ArgTy->isIncompleteType() ||3843 ParamTy->isUndeducedType() || ArgTy->isUndeducedType())3844 return;3845 3846 CharUnits ParamAlign = Context.getTypeAlignInChars(ParamTy);3847 CharUnits ArgAlign = Context.getTypeAlignInChars(ArgTy);3848 3849 // If the argument is less aligned than the parameter, there is a3850 // potential alignment issue.3851 if (ArgAlign < ParamAlign)3852 Diag(Loc, diag::warn_param_mismatched_alignment)3853 << (int)ArgAlign.getQuantity() << (int)ParamAlign.getQuantity()3854 << ParamName << (FDecl != nullptr) << FDecl;3855}3856 3857void Sema::checkLifetimeCaptureBy(FunctionDecl *FD, bool IsMemberFunction,3858 const Expr *ThisArg,3859 ArrayRef<const Expr *> Args) {3860 if (!FD || Args.empty())3861 return;3862 auto GetArgAt = [&](int Idx) -> const Expr * {3863 if (Idx == LifetimeCaptureByAttr::Global ||3864 Idx == LifetimeCaptureByAttr::Unknown)3865 return nullptr;3866 if (IsMemberFunction && Idx == 0)3867 return ThisArg;3868 return Args[Idx - IsMemberFunction];3869 };3870 auto HandleCaptureByAttr = [&](const LifetimeCaptureByAttr *Attr,3871 unsigned ArgIdx) {3872 if (!Attr)3873 return;3874 3875 Expr *Captured = const_cast<Expr *>(GetArgAt(ArgIdx));3876 for (int CapturingParamIdx : Attr->params()) {3877 // lifetime_capture_by(this) case is handled in the lifetimebound expr3878 // initialization codepath.3879 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&3880 isa<CXXConstructorDecl>(FD))3881 continue;3882 Expr *Capturing = const_cast<Expr *>(GetArgAt(CapturingParamIdx));3883 CapturingEntity CE{Capturing};3884 // Ensure that 'Captured' outlives the 'Capturing' entity.3885 checkCaptureByLifetime(*this, CE, Captured);3886 }3887 };3888 for (unsigned I = 0; I < FD->getNumParams(); ++I)3889 HandleCaptureByAttr(FD->getParamDecl(I)->getAttr<LifetimeCaptureByAttr>(),3890 I + IsMemberFunction);3891 // Check when the implicit object param is captured.3892 if (IsMemberFunction) {3893 TypeSourceInfo *TSI = FD->getTypeSourceInfo();3894 if (!TSI)3895 return;3896 AttributedTypeLoc ATL;3897 for (TypeLoc TL = TSI->getTypeLoc();3898 (ATL = TL.getAsAdjusted<AttributedTypeLoc>());3899 TL = ATL.getModifiedLoc())3900 HandleCaptureByAttr(ATL.getAttrAs<LifetimeCaptureByAttr>(), 0);3901 }3902}3903 3904void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,3905 const Expr *ThisArg, ArrayRef<const Expr *> Args,3906 bool IsMemberFunction, SourceLocation Loc,3907 SourceRange Range, VariadicCallType CallType) {3908 // FIXME: We should check as much as we can in the template definition.3909 if (CurContext->isDependentContext())3910 return;3911 3912 // Printf and scanf checking.3913 llvm::SmallBitVector CheckedVarArgs;3914 if (FDecl) {3915 for (const auto *I : FDecl->specific_attrs<FormatMatchesAttr>()) {3916 // Only create vector if there are format attributes.3917 CheckedVarArgs.resize(Args.size());3918 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,3919 CheckedVarArgs);3920 }3921 3922 for (const auto *I : FDecl->specific_attrs<FormatAttr>()) {3923 CheckedVarArgs.resize(Args.size());3924 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,3925 CheckedVarArgs);3926 }3927 }3928 3929 // Refuse POD arguments that weren't caught by the format string3930 // checks above.3931 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);3932 if (CallType != VariadicCallType::DoesNotApply &&3933 (!FD || FD->getBuiltinID() != Builtin::BI__noop)) {3934 unsigned NumParams = Proto ? Proto->getNumParams()3935 : isa_and_nonnull<FunctionDecl>(FDecl)3936 ? cast<FunctionDecl>(FDecl)->getNumParams()3937 : isa_and_nonnull<ObjCMethodDecl>(FDecl)3938 ? cast<ObjCMethodDecl>(FDecl)->param_size()3939 : 0;3940 3941 for (unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {3942 // Args[ArgIdx] can be null in malformed code.3943 if (const Expr *Arg = Args[ArgIdx]) {3944 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])3945 checkVariadicArgument(Arg, CallType);3946 }3947 }3948 }3949 if (FD)3950 checkLifetimeCaptureBy(FD, IsMemberFunction, ThisArg, Args);3951 if (FDecl || Proto) {3952 CheckNonNullArguments(*this, FDecl, Proto, Args, Loc);3953 3954 // Type safety checking.3955 if (FDecl) {3956 for (const auto *I : FDecl->specific_attrs<ArgumentWithTypeTagAttr>())3957 CheckArgumentWithTypeTag(I, Args, Loc);3958 }3959 }3960 3961 // Check that passed arguments match the alignment of original arguments.3962 // Try to get the missing prototype from the declaration.3963 if (!Proto && FDecl) {3964 const auto *FT = FDecl->getFunctionType();3965 if (isa_and_nonnull<FunctionProtoType>(FT))3966 Proto = cast<FunctionProtoType>(FDecl->getFunctionType());3967 }3968 if (Proto) {3969 // For variadic functions, we may have more args than parameters.3970 // For some K&R functions, we may have less args than parameters.3971 const auto N = std::min<unsigned>(Proto->getNumParams(), Args.size());3972 bool IsScalableRet = Proto->getReturnType()->isSizelessVectorType();3973 bool IsScalableArg = false;3974 for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {3975 // Args[ArgIdx] can be null in malformed code.3976 if (const Expr *Arg = Args[ArgIdx]) {3977 if (Arg->containsErrors())3978 continue;3979 3980 if (Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&3981 FDecl->hasLinkage() &&3982 FDecl->getFormalLinkage() != Linkage::Internal &&3983 CallType == VariadicCallType::DoesNotApply)3984 PPC().checkAIXMemberAlignment((Arg->getExprLoc()), Arg);3985 3986 QualType ParamTy = Proto->getParamType(ArgIdx);3987 if (ParamTy->isSizelessVectorType())3988 IsScalableArg = true;3989 QualType ArgTy = Arg->getType();3990 CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1),3991 ArgTy, ParamTy);3992 }3993 }3994 3995 // If the callee has an AArch64 SME attribute to indicate that it is an3996 // __arm_streaming function, then the caller requires SME to be available.3997 FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();3998 if (ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask) {3999 if (auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {4000 llvm::StringMap<bool> CallerFeatureMap;4001 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);4002 if (!CallerFeatureMap.contains("sme"))4003 Diag(Loc, diag::err_sme_call_in_non_sme_target);4004 } else if (!Context.getTargetInfo().hasFeature("sme")) {4005 Diag(Loc, diag::err_sme_call_in_non_sme_target);4006 }4007 }4008 4009 // If the call requires a streaming-mode change and has scalable vector4010 // arguments or return values, then warn the user that the streaming and4011 // non-streaming vector lengths may be different.4012 // When both streaming and non-streaming vector lengths are defined and4013 // mismatched, produce an error.4014 const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);4015 if (CallerFD && (!FD || !FD->getBuiltinID()) &&4016 (IsScalableArg || IsScalableRet)) {4017 bool IsCalleeStreaming =4018 ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;4019 bool IsCalleeStreamingCompatible =4020 ExtInfo.AArch64SMEAttributes &4021 FunctionType::SME_PStateSMCompatibleMask;4022 SemaARM::ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);4023 if (!IsCalleeStreamingCompatible &&4024 (CallerFnType == SemaARM::ArmStreamingCompatible ||4025 ((CallerFnType == SemaARM::ArmStreaming) ^ IsCalleeStreaming))) {4026 const LangOptions &LO = getLangOpts();4027 unsigned VL = LO.VScaleMin * 128;4028 unsigned SVL = LO.VScaleStreamingMin * 128;4029 bool IsVLMismatch = VL && SVL && VL != SVL;4030 4031 auto EmitDiag = [&](bool IsArg) {4032 if (IsVLMismatch) {4033 if (CallerFnType == SemaARM::ArmStreamingCompatible)4034 // Emit warning for streaming-compatible callers4035 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)4036 << IsArg << IsCalleeStreaming << SVL << VL;4037 else4038 // Emit error otherwise4039 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)4040 << IsArg << SVL << VL;4041 } else4042 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)4043 << IsArg;4044 };4045 4046 if (IsScalableArg)4047 EmitDiag(true);4048 if (IsScalableRet)4049 EmitDiag(false);4050 }4051 }4052 4053 FunctionType::ArmStateValue CalleeArmZAState =4054 FunctionType::getArmZAState(ExtInfo.AArch64SMEAttributes);4055 FunctionType::ArmStateValue CalleeArmZT0State =4056 FunctionType::getArmZT0State(ExtInfo.AArch64SMEAttributes);4057 if (CalleeArmZAState != FunctionType::ARM_None ||4058 CalleeArmZT0State != FunctionType::ARM_None) {4059 bool CallerHasZAState = false;4060 bool CallerHasZT0State = false;4061 if (CallerFD) {4062 auto *Attr = CallerFD->getAttr<ArmNewAttr>();4063 if (Attr && Attr->isNewZA())4064 CallerHasZAState = true;4065 if (Attr && Attr->isNewZT0())4066 CallerHasZT0State = true;4067 if (const auto *FPT = CallerFD->getType()->getAs<FunctionProtoType>()) {4068 CallerHasZAState |=4069 FunctionType::getArmZAState(4070 FPT->getExtProtoInfo().AArch64SMEAttributes) !=4071 FunctionType::ARM_None;4072 CallerHasZT0State |=4073 FunctionType::getArmZT0State(4074 FPT->getExtProtoInfo().AArch64SMEAttributes) !=4075 FunctionType::ARM_None;4076 }4077 }4078 4079 if (CalleeArmZAState != FunctionType::ARM_None && !CallerHasZAState)4080 Diag(Loc, diag::err_sme_za_call_no_za_state);4081 4082 if (CalleeArmZT0State != FunctionType::ARM_None && !CallerHasZT0State)4083 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);4084 4085 if (CallerHasZAState && CalleeArmZAState == FunctionType::ARM_None &&4086 CalleeArmZT0State != FunctionType::ARM_None) {4087 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);4088 Diag(Loc, diag::note_sme_use_preserves_za);4089 }4090 }4091 }4092 4093 if (FDecl && FDecl->hasAttr<AllocAlignAttr>()) {4094 auto *AA = FDecl->getAttr<AllocAlignAttr>();4095 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];4096 if (!Arg->isValueDependent()) {4097 Expr::EvalResult Align;4098 if (Arg->EvaluateAsInt(Align, Context)) {4099 const llvm::APSInt &I = Align.Val.getInt();4100 if (!I.isPowerOf2())4101 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)4102 << Arg->getSourceRange();4103 4104 if (I > Sema::MaximumAlignment)4105 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)4106 << Arg->getSourceRange() << Sema::MaximumAlignment;4107 }4108 }4109 }4110 4111 if (FD)4112 diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);4113}4114 4115void Sema::CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc) {4116 if (TemplateDecl *Decl = AutoT->getTypeConstraintConcept()) {4117 DiagnoseUseOfDecl(Decl, Loc);4118 }4119}4120 4121void Sema::CheckConstructorCall(FunctionDecl *FDecl, QualType ThisType,4122 ArrayRef<const Expr *> Args,4123 const FunctionProtoType *Proto,4124 SourceLocation Loc) {4125 VariadicCallType CallType = Proto->isVariadic()4126 ? VariadicCallType::Constructor4127 : VariadicCallType::DoesNotApply;4128 4129 auto *Ctor = cast<CXXConstructorDecl>(FDecl);4130 CheckArgAlignment(4131 Loc, FDecl, "'this'", Context.getPointerType(ThisType),4132 Context.getPointerType(Ctor->getFunctionObjectParameterType()));4133 4134 checkCall(FDecl, Proto, /*ThisArg=*/nullptr, Args, /*IsMemberFunction=*/true,4135 Loc, SourceRange(), CallType);4136}4137 4138bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,4139 const FunctionProtoType *Proto) {4140 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&4141 isa<CXXMethodDecl>(FDecl);4142 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||4143 IsMemberOperatorCall;4144 VariadicCallType CallType = getVariadicCallType(FDecl, Proto,4145 TheCall->getCallee());4146 Expr** Args = TheCall->getArgs();4147 unsigned NumArgs = TheCall->getNumArgs();4148 4149 Expr *ImplicitThis = nullptr;4150 if (IsMemberOperatorCall && !FDecl->hasCXXExplicitFunctionObjectParameter()) {4151 // If this is a call to a member operator, hide the first4152 // argument from checkCall.4153 // FIXME: Our choice of AST representation here is less than ideal.4154 ImplicitThis = Args[0];4155 ++Args;4156 --NumArgs;4157 } else if (IsMemberFunction && !FDecl->isStatic() &&4158 !FDecl->hasCXXExplicitFunctionObjectParameter())4159 ImplicitThis =4160 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();4161 4162 if (ImplicitThis) {4163 // ImplicitThis may or may not be a pointer, depending on whether . or -> is4164 // used.4165 QualType ThisType = ImplicitThis->getType();4166 if (!ThisType->isPointerType()) {4167 assert(!ThisType->isReferenceType());4168 ThisType = Context.getPointerType(ThisType);4169 }4170 4171 QualType ThisTypeFromDecl = Context.getPointerType(4172 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());4173 4174 CheckArgAlignment(TheCall->getRParenLoc(), FDecl, "'this'", ThisType,4175 ThisTypeFromDecl);4176 }4177 4178 checkCall(FDecl, Proto, ImplicitThis, llvm::ArrayRef(Args, NumArgs),4179 IsMemberFunction, TheCall->getRParenLoc(),4180 TheCall->getCallee()->getSourceRange(), CallType);4181 4182 IdentifierInfo *FnInfo = FDecl->getIdentifier();4183 // None of the checks below are needed for functions that don't have4184 // simple names (e.g., C++ conversion functions).4185 if (!FnInfo)4186 return false;4187 4188 // Enforce TCB except for builtin calls, which are always allowed.4189 if (FDecl->getBuiltinID() == 0)4190 CheckTCBEnforcement(TheCall->getExprLoc(), FDecl);4191 4192 CheckAbsoluteValueFunction(TheCall, FDecl);4193 CheckMaxUnsignedZero(TheCall, FDecl);4194 CheckInfNaNFunction(TheCall, FDecl);4195 4196 if (getLangOpts().ObjC)4197 ObjC().DiagnoseCStringFormatDirectiveInCFAPI(FDecl, Args, NumArgs);4198 4199 unsigned CMId = FDecl->getMemoryFunctionKind();4200 4201 // Handle memory setting and copying functions.4202 switch (CMId) {4203 case 0:4204 return false;4205 case Builtin::BIstrlcpy: // fallthrough4206 case Builtin::BIstrlcat:4207 CheckStrlcpycatArguments(TheCall, FnInfo);4208 break;4209 case Builtin::BIstrncat:4210 CheckStrncatArguments(TheCall, FnInfo);4211 break;4212 case Builtin::BIfree:4213 CheckFreeArguments(TheCall);4214 break;4215 default:4216 CheckMemaccessArguments(TheCall, CMId, FnInfo);4217 }4218 4219 return false;4220}4221 4222bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,4223 const FunctionProtoType *Proto) {4224 QualType Ty;4225 if (const auto *V = dyn_cast<VarDecl>(NDecl))4226 Ty = V->getType().getNonReferenceType();4227 else if (const auto *F = dyn_cast<FieldDecl>(NDecl))4228 Ty = F->getType().getNonReferenceType();4229 else4230 return false;4231 4232 if (!Ty->isBlockPointerType() && !Ty->isFunctionPointerType() &&4233 !Ty->isFunctionProtoType())4234 return false;4235 4236 VariadicCallType CallType;4237 if (!Proto || !Proto->isVariadic()) {4238 CallType = VariadicCallType::DoesNotApply;4239 } else if (Ty->isBlockPointerType()) {4240 CallType = VariadicCallType::Block;4241 } else { // Ty->isFunctionPointerType()4242 CallType = VariadicCallType::Function;4243 }4244 4245 checkCall(NDecl, Proto, /*ThisArg=*/nullptr,4246 llvm::ArrayRef(TheCall->getArgs(), TheCall->getNumArgs()),4247 /*IsMemberFunction=*/false, TheCall->getRParenLoc(),4248 TheCall->getCallee()->getSourceRange(), CallType);4249 4250 return false;4251}4252 4253bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) {4254 VariadicCallType CallType = getVariadicCallType(/*FDecl=*/nullptr, Proto,4255 TheCall->getCallee());4256 checkCall(/*FDecl=*/nullptr, Proto, /*ThisArg=*/nullptr,4257 llvm::ArrayRef(TheCall->getArgs(), TheCall->getNumArgs()),4258 /*IsMemberFunction=*/false, TheCall->getRParenLoc(),4259 TheCall->getCallee()->getSourceRange(), CallType);4260 4261 return false;4262}4263 4264static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) {4265 if (!llvm::isValidAtomicOrderingCABI(Ordering))4266 return false;4267 4268 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;4269 switch (Op) {4270 case AtomicExpr::AO__c11_atomic_init:4271 case AtomicExpr::AO__opencl_atomic_init:4272 llvm_unreachable("There is no ordering argument for an init");4273 4274 case AtomicExpr::AO__c11_atomic_load:4275 case AtomicExpr::AO__opencl_atomic_load:4276 case AtomicExpr::AO__hip_atomic_load:4277 case AtomicExpr::AO__atomic_load_n:4278 case AtomicExpr::AO__atomic_load:4279 case AtomicExpr::AO__scoped_atomic_load_n:4280 case AtomicExpr::AO__scoped_atomic_load:4281 return OrderingCABI != llvm::AtomicOrderingCABI::release &&4282 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;4283 4284 case AtomicExpr::AO__c11_atomic_store:4285 case AtomicExpr::AO__opencl_atomic_store:4286 case AtomicExpr::AO__hip_atomic_store:4287 case AtomicExpr::AO__atomic_store:4288 case AtomicExpr::AO__atomic_store_n:4289 case AtomicExpr::AO__scoped_atomic_store:4290 case AtomicExpr::AO__scoped_atomic_store_n:4291 case AtomicExpr::AO__atomic_clear:4292 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&4293 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&4294 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;4295 4296 default:4297 return true;4298 }4299}4300 4301ExprResult Sema::AtomicOpsOverloaded(ExprResult TheCallResult,4302 AtomicExpr::AtomicOp Op) {4303 CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());4304 DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());4305 MultiExprArg Args{TheCall->getArgs(), TheCall->getNumArgs()};4306 return BuildAtomicExpr({TheCall->getBeginLoc(), TheCall->getEndLoc()},4307 DRE->getSourceRange(), TheCall->getRParenLoc(), Args,4308 Op);4309}4310 4311ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,4312 SourceLocation RParenLoc, MultiExprArg Args,4313 AtomicExpr::AtomicOp Op,4314 AtomicArgumentOrder ArgOrder) {4315 // All the non-OpenCL operations take one of the following forms.4316 // The OpenCL operations take the __c11 forms with one extra argument for4317 // synchronization scope.4318 enum {4319 // C __c11_atomic_init(A *, C)4320 Init,4321 4322 // C __c11_atomic_load(A *, int)4323 Load,4324 4325 // void __atomic_load(A *, CP, int)4326 LoadCopy,4327 4328 // void __atomic_store(A *, CP, int)4329 Copy,4330 4331 // C __c11_atomic_add(A *, M, int)4332 Arithmetic,4333 4334 // C __atomic_exchange_n(A *, CP, int)4335 Xchg,4336 4337 // void __atomic_exchange(A *, C *, CP, int)4338 GNUXchg,4339 4340 // bool __c11_atomic_compare_exchange_strong(A *, C *, CP, int, int)4341 C11CmpXchg,4342 4343 // bool __atomic_compare_exchange(A *, C *, CP, bool, int, int)4344 GNUCmpXchg,4345 4346 // bool __atomic_test_and_set(A *, int)4347 TestAndSetByte,4348 4349 // void __atomic_clear(A *, int)4350 ClearByte,4351 } Form = Init;4352 4353 const unsigned NumForm = ClearByte + 1;4354 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};4355 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};4356 // where:4357 // C is an appropriate type,4358 // A is volatile _Atomic(C) for __c11 builtins and is C for GNU builtins,4359 // CP is C for __c11 builtins and GNU _n builtins and is C * otherwise,4360 // M is C if C is an integer, and ptrdiff_t if C is a pointer, and4361 // the int parameters are for orderings.4362 4363 static_assert(sizeof(NumArgs)/sizeof(NumArgs[0]) == NumForm4364 && sizeof(NumVals)/sizeof(NumVals[0]) == NumForm,4365 "need to update code for modified forms");4366 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&4367 AtomicExpr::AO__atomic_xor_fetch + 1 ==4368 AtomicExpr::AO__c11_atomic_compare_exchange_strong,4369 "need to update code for modified C11 atomics");4370 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&4371 Op <= AtomicExpr::AO__opencl_atomic_store;4372 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&4373 Op <= AtomicExpr::AO__hip_atomic_store;4374 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&4375 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;4376 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&4377 Op <= AtomicExpr::AO__c11_atomic_store) ||4378 IsOpenCL;4379 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||4380 Op == AtomicExpr::AO__atomic_store_n ||4381 Op == AtomicExpr::AO__atomic_exchange_n ||4382 Op == AtomicExpr::AO__atomic_compare_exchange_n ||4383 Op == AtomicExpr::AO__scoped_atomic_load_n ||4384 Op == AtomicExpr::AO__scoped_atomic_store_n ||4385 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||4386 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;4387 // Bit mask for extra allowed value types other than integers for atomic4388 // arithmetic operations. Add/sub allow pointer and floating point. Min/max4389 // allow floating point.4390 enum ArithOpExtraValueType {4391 AOEVT_None = 0,4392 AOEVT_Pointer = 1,4393 AOEVT_FP = 2,4394 };4395 unsigned ArithAllows = AOEVT_None;4396 4397 switch (Op) {4398 case AtomicExpr::AO__c11_atomic_init:4399 case AtomicExpr::AO__opencl_atomic_init:4400 Form = Init;4401 break;4402 4403 case AtomicExpr::AO__c11_atomic_load:4404 case AtomicExpr::AO__opencl_atomic_load:4405 case AtomicExpr::AO__hip_atomic_load:4406 case AtomicExpr::AO__atomic_load_n:4407 case AtomicExpr::AO__scoped_atomic_load_n:4408 Form = Load;4409 break;4410 4411 case AtomicExpr::AO__atomic_load:4412 case AtomicExpr::AO__scoped_atomic_load:4413 Form = LoadCopy;4414 break;4415 4416 case AtomicExpr::AO__c11_atomic_store:4417 case AtomicExpr::AO__opencl_atomic_store:4418 case AtomicExpr::AO__hip_atomic_store:4419 case AtomicExpr::AO__atomic_store:4420 case AtomicExpr::AO__atomic_store_n:4421 case AtomicExpr::AO__scoped_atomic_store:4422 case AtomicExpr::AO__scoped_atomic_store_n:4423 Form = Copy;4424 break;4425 case AtomicExpr::AO__atomic_fetch_add:4426 case AtomicExpr::AO__atomic_fetch_sub:4427 case AtomicExpr::AO__atomic_add_fetch:4428 case AtomicExpr::AO__atomic_sub_fetch:4429 case AtomicExpr::AO__scoped_atomic_fetch_add:4430 case AtomicExpr::AO__scoped_atomic_fetch_sub:4431 case AtomicExpr::AO__scoped_atomic_add_fetch:4432 case AtomicExpr::AO__scoped_atomic_sub_fetch:4433 case AtomicExpr::AO__c11_atomic_fetch_add:4434 case AtomicExpr::AO__c11_atomic_fetch_sub:4435 case AtomicExpr::AO__opencl_atomic_fetch_add:4436 case AtomicExpr::AO__opencl_atomic_fetch_sub:4437 case AtomicExpr::AO__hip_atomic_fetch_add:4438 case AtomicExpr::AO__hip_atomic_fetch_sub:4439 ArithAllows = AOEVT_Pointer | AOEVT_FP;4440 Form = Arithmetic;4441 break;4442 case AtomicExpr::AO__atomic_fetch_max:4443 case AtomicExpr::AO__atomic_fetch_min:4444 case AtomicExpr::AO__atomic_max_fetch:4445 case AtomicExpr::AO__atomic_min_fetch:4446 case AtomicExpr::AO__scoped_atomic_fetch_max:4447 case AtomicExpr::AO__scoped_atomic_fetch_min:4448 case AtomicExpr::AO__scoped_atomic_max_fetch:4449 case AtomicExpr::AO__scoped_atomic_min_fetch:4450 case AtomicExpr::AO__c11_atomic_fetch_max:4451 case AtomicExpr::AO__c11_atomic_fetch_min:4452 case AtomicExpr::AO__opencl_atomic_fetch_max:4453 case AtomicExpr::AO__opencl_atomic_fetch_min:4454 case AtomicExpr::AO__hip_atomic_fetch_max:4455 case AtomicExpr::AO__hip_atomic_fetch_min:4456 ArithAllows = AOEVT_FP;4457 Form = Arithmetic;4458 break;4459 case AtomicExpr::AO__c11_atomic_fetch_and:4460 case AtomicExpr::AO__c11_atomic_fetch_or:4461 case AtomicExpr::AO__c11_atomic_fetch_xor:4462 case AtomicExpr::AO__hip_atomic_fetch_and:4463 case AtomicExpr::AO__hip_atomic_fetch_or:4464 case AtomicExpr::AO__hip_atomic_fetch_xor:4465 case AtomicExpr::AO__c11_atomic_fetch_nand:4466 case AtomicExpr::AO__opencl_atomic_fetch_and:4467 case AtomicExpr::AO__opencl_atomic_fetch_or:4468 case AtomicExpr::AO__opencl_atomic_fetch_xor:4469 case AtomicExpr::AO__atomic_fetch_and:4470 case AtomicExpr::AO__atomic_fetch_or:4471 case AtomicExpr::AO__atomic_fetch_xor:4472 case AtomicExpr::AO__atomic_fetch_nand:4473 case AtomicExpr::AO__atomic_and_fetch:4474 case AtomicExpr::AO__atomic_or_fetch:4475 case AtomicExpr::AO__atomic_xor_fetch:4476 case AtomicExpr::AO__atomic_nand_fetch:4477 case AtomicExpr::AO__scoped_atomic_fetch_and:4478 case AtomicExpr::AO__scoped_atomic_fetch_or:4479 case AtomicExpr::AO__scoped_atomic_fetch_xor:4480 case AtomicExpr::AO__scoped_atomic_fetch_nand:4481 case AtomicExpr::AO__scoped_atomic_and_fetch:4482 case AtomicExpr::AO__scoped_atomic_or_fetch:4483 case AtomicExpr::AO__scoped_atomic_xor_fetch:4484 case AtomicExpr::AO__scoped_atomic_nand_fetch:4485 case AtomicExpr::AO__scoped_atomic_uinc_wrap:4486 case AtomicExpr::AO__scoped_atomic_udec_wrap:4487 Form = Arithmetic;4488 break;4489 4490 case AtomicExpr::AO__c11_atomic_exchange:4491 case AtomicExpr::AO__hip_atomic_exchange:4492 case AtomicExpr::AO__opencl_atomic_exchange:4493 case AtomicExpr::AO__atomic_exchange_n:4494 case AtomicExpr::AO__scoped_atomic_exchange_n:4495 Form = Xchg;4496 break;4497 4498 case AtomicExpr::AO__atomic_exchange:4499 case AtomicExpr::AO__scoped_atomic_exchange:4500 Form = GNUXchg;4501 break;4502 4503 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:4504 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:4505 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:4506 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:4507 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:4508 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:4509 Form = C11CmpXchg;4510 break;4511 4512 case AtomicExpr::AO__atomic_compare_exchange:4513 case AtomicExpr::AO__atomic_compare_exchange_n:4514 case AtomicExpr::AO__scoped_atomic_compare_exchange:4515 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:4516 Form = GNUCmpXchg;4517 break;4518 4519 case AtomicExpr::AO__atomic_test_and_set:4520 Form = TestAndSetByte;4521 break;4522 4523 case AtomicExpr::AO__atomic_clear:4524 Form = ClearByte;4525 break;4526 }4527 4528 unsigned AdjustedNumArgs = NumArgs[Form];4529 if ((IsOpenCL || IsHIP || IsScoped) &&4530 Op != AtomicExpr::AO__opencl_atomic_init)4531 ++AdjustedNumArgs;4532 // Check we have the right number of arguments.4533 if (Args.size() < AdjustedNumArgs) {4534 Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args)4535 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())4536 << /*is non object*/ 0 << ExprRange;4537 return ExprError();4538 } else if (Args.size() > AdjustedNumArgs) {4539 Diag(Args[AdjustedNumArgs]->getBeginLoc(),4540 diag::err_typecheck_call_too_many_args)4541 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())4542 << /*is non object*/ 0 << ExprRange;4543 return ExprError();4544 }4545 4546 // Inspect the first argument of the atomic operation.4547 Expr *Ptr = Args[0];4548 ExprResult ConvertedPtr = DefaultFunctionArrayLvalueConversion(Ptr);4549 if (ConvertedPtr.isInvalid())4550 return ExprError();4551 4552 Ptr = ConvertedPtr.get();4553 const PointerType *pointerType = Ptr->getType()->getAs<PointerType>();4554 if (!pointerType) {4555 Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)4556 << Ptr->getType() << 0 << Ptr->getSourceRange();4557 return ExprError();4558 }4559 4560 // For a __c11 builtin, this should be a pointer to an _Atomic type.4561 QualType AtomTy = pointerType->getPointeeType(); // 'A'4562 QualType ValType = AtomTy; // 'C'4563 if (IsC11) {4564 if (!AtomTy->isAtomicType()) {4565 Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic)4566 << Ptr->getType() << Ptr->getSourceRange();4567 return ExprError();4568 }4569 if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) ||4570 AtomTy.getAddressSpace() == LangAS::opencl_constant) {4571 Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_non_const_atomic)4572 << (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType()4573 << Ptr->getSourceRange();4574 return ExprError();4575 }4576 ValType = AtomTy->castAs<AtomicType>()->getValueType();4577 } else if (Form != Load && Form != LoadCopy) {4578 if (ValType.isConstQualified()) {4579 Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_non_const_pointer)4580 << Ptr->getType() << Ptr->getSourceRange();4581 return ExprError();4582 }4583 }4584 4585 if (Form != TestAndSetByte && Form != ClearByte) {4586 // Pointer to object of size zero is not allowed.4587 if (RequireCompleteType(Ptr->getBeginLoc(), AtomTy,4588 diag::err_incomplete_type))4589 return ExprError();4590 4591 if (Context.getTypeInfoInChars(AtomTy).Width.isZero()) {4592 Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)4593 << Ptr->getType() << 1 << Ptr->getSourceRange();4594 return ExprError();4595 }4596 } else {4597 // The __atomic_clear and __atomic_test_and_set intrinsics accept any4598 // non-const pointer type, including void* and pointers to incomplete4599 // structs, but only access the first byte.4600 AtomTy = Context.CharTy;4601 AtomTy = AtomTy.withCVRQualifiers(4602 pointerType->getPointeeType().getCVRQualifiers());4603 QualType PointerQT = Context.getPointerType(AtomTy);4604 pointerType = PointerQT->getAs<PointerType>();4605 Ptr = ImpCastExprToType(Ptr, PointerQT, CK_BitCast).get();4606 ValType = AtomTy;4607 }4608 4609 PointerAuthQualifier PointerAuth = AtomTy.getPointerAuth();4610 if (PointerAuth && PointerAuth.isAddressDiscriminated()) {4611 Diag(ExprRange.getBegin(),4612 diag::err_atomic_op_needs_non_address_discriminated_pointer)4613 << 0 << Ptr->getType() << Ptr->getSourceRange();4614 return ExprError();4615 }4616 4617 // For an arithmetic operation, the implied arithmetic must be well-formed.4618 if (Form == Arithmetic) {4619 // GCC does not enforce these rules for GNU atomics, but we do to help catch4620 // trivial type errors.4621 auto IsAllowedValueType = [&](QualType ValType,4622 unsigned AllowedType) -> bool {4623 if (ValType->isIntegerType())4624 return true;4625 if (ValType->isPointerType())4626 return AllowedType & AOEVT_Pointer;4627 if (!(ValType->isFloatingType() && (AllowedType & AOEVT_FP)))4628 return false;4629 // LLVM Parser does not allow atomicrmw with x86_fp80 type.4630 if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&4631 &Context.getTargetInfo().getLongDoubleFormat() ==4632 &llvm::APFloat::x87DoubleExtended())4633 return false;4634 return true;4635 };4636 if (!IsAllowedValueType(ValType, ArithAllows)) {4637 auto DID = ArithAllows & AOEVT_FP4638 ? (ArithAllows & AOEVT_Pointer4639 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp4640 : diag::err_atomic_op_needs_atomic_int_or_fp)4641 : diag::err_atomic_op_needs_atomic_int;4642 Diag(ExprRange.getBegin(), DID)4643 << IsC11 << Ptr->getType() << Ptr->getSourceRange();4644 return ExprError();4645 }4646 if (IsC11 && ValType->isPointerType() &&4647 RequireCompleteType(Ptr->getBeginLoc(), ValType->getPointeeType(),4648 diag::err_incomplete_type)) {4649 return ExprError();4650 }4651 } else if (IsN && !ValType->isIntegerType() && !ValType->isPointerType()) {4652 // For __atomic_*_n operations, the value type must be a scalar integral or4653 // pointer type which is 1, 2, 4, 8 or 16 bytes in length.4654 Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)4655 << IsC11 << Ptr->getType() << Ptr->getSourceRange();4656 return ExprError();4657 }4658 4659 if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context) &&4660 !AtomTy->isScalarType()) {4661 // For GNU atomics, require a trivially-copyable type. This is not part of4662 // the GNU atomics specification but we enforce it for consistency with4663 // other atomics which generally all require a trivially-copyable type. This4664 // is because atomics just copy bits.4665 Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_trivial_copy)4666 << Ptr->getType() << Ptr->getSourceRange();4667 return ExprError();4668 }4669 4670 switch (ValType.getObjCLifetime()) {4671 case Qualifiers::OCL_None:4672 case Qualifiers::OCL_ExplicitNone:4673 // okay4674 break;4675 4676 case Qualifiers::OCL_Weak:4677 case Qualifiers::OCL_Strong:4678 case Qualifiers::OCL_Autoreleasing:4679 // FIXME: Can this happen? By this point, ValType should be known4680 // to be trivially copyable.4681 Diag(ExprRange.getBegin(), diag::err_arc_atomic_ownership)4682 << ValType << Ptr->getSourceRange();4683 return ExprError();4684 }4685 4686 // All atomic operations have an overload which takes a pointer to a volatile4687 // 'A'. We shouldn't let the volatile-ness of the pointee-type inject itself4688 // into the result or the other operands. Similarly atomic_load takes a4689 // pointer to a const 'A'.4690 ValType.removeLocalVolatile();4691 ValType.removeLocalConst();4692 QualType ResultType = ValType;4693 if (Form == Copy || Form == LoadCopy || Form == GNUXchg || Form == Init ||4694 Form == ClearByte)4695 ResultType = Context.VoidTy;4696 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)4697 ResultType = Context.BoolTy;4698 4699 // The type of a parameter passed 'by value'. In the GNU atomics, such4700 // arguments are actually passed as pointers.4701 QualType ByValType = ValType; // 'CP'4702 bool IsPassedByAddress = false;4703 if (!IsC11 && !IsHIP && !IsN) {4704 ByValType = Ptr->getType();4705 IsPassedByAddress = true;4706 }4707 4708 SmallVector<Expr *, 5> APIOrderedArgs;4709 if (ArgOrder == Sema::AtomicArgumentOrder::AST) {4710 APIOrderedArgs.push_back(Args[0]);4711 switch (Form) {4712 case Init:4713 case Load:4714 APIOrderedArgs.push_back(Args[1]); // Val1/Order4715 break;4716 case LoadCopy:4717 case Copy:4718 case Arithmetic:4719 case Xchg:4720 APIOrderedArgs.push_back(Args[2]); // Val14721 APIOrderedArgs.push_back(Args[1]); // Order4722 break;4723 case GNUXchg:4724 APIOrderedArgs.push_back(Args[2]); // Val14725 APIOrderedArgs.push_back(Args[3]); // Val24726 APIOrderedArgs.push_back(Args[1]); // Order4727 break;4728 case C11CmpXchg:4729 APIOrderedArgs.push_back(Args[2]); // Val14730 APIOrderedArgs.push_back(Args[4]); // Val24731 APIOrderedArgs.push_back(Args[1]); // Order4732 APIOrderedArgs.push_back(Args[3]); // OrderFail4733 break;4734 case GNUCmpXchg:4735 APIOrderedArgs.push_back(Args[2]); // Val14736 APIOrderedArgs.push_back(Args[4]); // Val24737 APIOrderedArgs.push_back(Args[5]); // Weak4738 APIOrderedArgs.push_back(Args[1]); // Order4739 APIOrderedArgs.push_back(Args[3]); // OrderFail4740 break;4741 case TestAndSetByte:4742 case ClearByte:4743 APIOrderedArgs.push_back(Args[1]); // Order4744 break;4745 }4746 } else4747 APIOrderedArgs.append(Args.begin(), Args.end());4748 4749 // The first argument's non-CV pointer type is used to deduce the type of4750 // subsequent arguments, except for:4751 // - weak flag (always converted to bool)4752 // - memory order (always converted to int)4753 // - scope (always converted to int)4754 for (unsigned i = 0; i != APIOrderedArgs.size(); ++i) {4755 QualType Ty;4756 if (i < NumVals[Form] + 1) {4757 switch (i) {4758 case 0:4759 // The first argument is always a pointer. It has a fixed type.4760 // It is always dereferenced, a nullptr is undefined.4761 CheckNonNullArgument(*this, APIOrderedArgs[i], ExprRange.getBegin());4762 // Nothing else to do: we already know all we want about this pointer.4763 continue;4764 case 1:4765 // The second argument is the non-atomic operand. For arithmetic, this4766 // is always passed by value, and for a compare_exchange it is always4767 // passed by address. For the rest, GNU uses by-address and C11 uses4768 // by-value.4769 assert(Form != Load);4770 if (Form == Arithmetic && ValType->isPointerType())4771 Ty = Context.getPointerDiffType();4772 else if (Form == Init || Form == Arithmetic)4773 Ty = ValType;4774 else if (Form == Copy || Form == Xchg) {4775 if (IsPassedByAddress) {4776 // The value pointer is always dereferenced, a nullptr is undefined.4777 CheckNonNullArgument(*this, APIOrderedArgs[i],4778 ExprRange.getBegin());4779 }4780 Ty = ByValType;4781 } else {4782 Expr *ValArg = APIOrderedArgs[i];4783 // The value pointer is always dereferenced, a nullptr is undefined.4784 CheckNonNullArgument(*this, ValArg, ExprRange.getBegin());4785 LangAS AS = LangAS::Default;4786 // Keep address space of non-atomic pointer type.4787 if (const PointerType *PtrTy =4788 ValArg->getType()->getAs<PointerType>()) {4789 AS = PtrTy->getPointeeType().getAddressSpace();4790 }4791 Ty = Context.getPointerType(4792 Context.getAddrSpaceQualType(ValType.getUnqualifiedType(), AS));4793 }4794 break;4795 case 2:4796 // The third argument to compare_exchange / GNU exchange is the desired4797 // value, either by-value (for the C11 and *_n variant) or as a pointer.4798 if (IsPassedByAddress)4799 CheckNonNullArgument(*this, APIOrderedArgs[i], ExprRange.getBegin());4800 Ty = ByValType;4801 break;4802 case 3:4803 // The fourth argument to GNU compare_exchange is a 'weak' flag.4804 Ty = Context.BoolTy;4805 break;4806 }4807 } else {4808 // The order(s) and scope are always converted to int.4809 Ty = Context.IntTy;4810 }4811 4812 InitializedEntity Entity =4813 InitializedEntity::InitializeParameter(Context, Ty, false);4814 ExprResult Arg = APIOrderedArgs[i];4815 Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);4816 if (Arg.isInvalid())4817 return true;4818 APIOrderedArgs[i] = Arg.get();4819 }4820 4821 // Permute the arguments into a 'consistent' order.4822 SmallVector<Expr*, 5> SubExprs;4823 SubExprs.push_back(Ptr);4824 switch (Form) {4825 case Init:4826 // Note, AtomicExpr::getVal1() has a special case for this atomic.4827 SubExprs.push_back(APIOrderedArgs[1]); // Val14828 break;4829 case Load:4830 case TestAndSetByte:4831 case ClearByte:4832 SubExprs.push_back(APIOrderedArgs[1]); // Order4833 break;4834 case LoadCopy:4835 case Copy:4836 case Arithmetic:4837 case Xchg:4838 SubExprs.push_back(APIOrderedArgs[2]); // Order4839 SubExprs.push_back(APIOrderedArgs[1]); // Val14840 break;4841 case GNUXchg:4842 // Note, AtomicExpr::getVal2() has a special case for this atomic.4843 SubExprs.push_back(APIOrderedArgs[3]); // Order4844 SubExprs.push_back(APIOrderedArgs[1]); // Val14845 SubExprs.push_back(APIOrderedArgs[2]); // Val24846 break;4847 case C11CmpXchg:4848 SubExprs.push_back(APIOrderedArgs[3]); // Order4849 SubExprs.push_back(APIOrderedArgs[1]); // Val14850 SubExprs.push_back(APIOrderedArgs[4]); // OrderFail4851 SubExprs.push_back(APIOrderedArgs[2]); // Val24852 break;4853 case GNUCmpXchg:4854 SubExprs.push_back(APIOrderedArgs[4]); // Order4855 SubExprs.push_back(APIOrderedArgs[1]); // Val14856 SubExprs.push_back(APIOrderedArgs[5]); // OrderFail4857 SubExprs.push_back(APIOrderedArgs[2]); // Val24858 SubExprs.push_back(APIOrderedArgs[3]); // Weak4859 break;4860 }4861 4862 // If the memory orders are constants, check they are valid.4863 if (SubExprs.size() >= 2 && Form != Init) {4864 std::optional<llvm::APSInt> Success =4865 SubExprs[1]->getIntegerConstantExpr(Context);4866 if (Success && !isValidOrderingForOp(Success->getSExtValue(), Op)) {4867 Diag(SubExprs[1]->getBeginLoc(),4868 diag::warn_atomic_op_has_invalid_memory_order)4869 << /*success=*/(Form == C11CmpXchg || Form == GNUCmpXchg)4870 << SubExprs[1]->getSourceRange();4871 }4872 if (SubExprs.size() >= 5) {4873 if (std::optional<llvm::APSInt> Failure =4874 SubExprs[3]->getIntegerConstantExpr(Context)) {4875 if (!llvm::is_contained(4876 {llvm::AtomicOrderingCABI::relaxed,4877 llvm::AtomicOrderingCABI::consume,4878 llvm::AtomicOrderingCABI::acquire,4879 llvm::AtomicOrderingCABI::seq_cst},4880 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {4881 Diag(SubExprs[3]->getBeginLoc(),4882 diag::warn_atomic_op_has_invalid_memory_order)4883 << /*failure=*/2 << SubExprs[3]->getSourceRange();4884 }4885 }4886 }4887 }4888 4889 if (auto ScopeModel = AtomicExpr::getScopeModel(Op)) {4890 auto *Scope = Args[Args.size() - 1];4891 if (std::optional<llvm::APSInt> Result =4892 Scope->getIntegerConstantExpr(Context)) {4893 if (!ScopeModel->isValid(Result->getZExtValue()))4894 Diag(Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)4895 << Scope->getSourceRange();4896 }4897 SubExprs.push_back(Scope);4898 }4899 4900 AtomicExpr *AE = new (Context)4901 AtomicExpr(ExprRange.getBegin(), SubExprs, ResultType, Op, RParenLoc);4902 4903 if ((Op == AtomicExpr::AO__c11_atomic_load ||4904 Op == AtomicExpr::AO__c11_atomic_store ||4905 Op == AtomicExpr::AO__opencl_atomic_load ||4906 Op == AtomicExpr::AO__hip_atomic_load ||4907 Op == AtomicExpr::AO__opencl_atomic_store ||4908 Op == AtomicExpr::AO__hip_atomic_store) &&4909 Context.AtomicUsesUnsupportedLibcall(AE))4910 Diag(AE->getBeginLoc(), diag::err_atomic_load_store_uses_lib)4911 << ((Op == AtomicExpr::AO__c11_atomic_load ||4912 Op == AtomicExpr::AO__opencl_atomic_load ||4913 Op == AtomicExpr::AO__hip_atomic_load)4914 ? 04915 : 1);4916 4917 if (ValType->isBitIntType()) {4918 Diag(Ptr->getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);4919 return ExprError();4920 }4921 4922 return AE;4923}4924 4925/// checkBuiltinArgument - Given a call to a builtin function, perform4926/// normal type-checking on the given argument, updating the call in4927/// place. This is useful when a builtin function requires custom4928/// type-checking for some of its arguments but not necessarily all of4929/// them.4930///4931/// Returns true on error.4932static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) {4933 FunctionDecl *Fn = E->getDirectCallee();4934 assert(Fn && "builtin call without direct callee!");4935 4936 ParmVarDecl *Param = Fn->getParamDecl(ArgIndex);4937 InitializedEntity Entity =4938 InitializedEntity::InitializeParameter(S.Context, Param);4939 4940 ExprResult Arg = E->getArg(ArgIndex);4941 Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg);4942 if (Arg.isInvalid())4943 return true;4944 4945 E->setArg(ArgIndex, Arg.get());4946 return false;4947}4948 4949ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) {4950 CallExpr *TheCall = static_cast<CallExpr *>(TheCallResult.get());4951 Expr *Callee = TheCall->getCallee();4952 DeclRefExpr *DRE = cast<DeclRefExpr>(Callee->IgnoreParenCasts());4953 FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());4954 4955 // Ensure that we have at least one argument to do type inference from.4956 if (TheCall->getNumArgs() < 1) {4957 Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)4958 << 0 << 1 << TheCall->getNumArgs() << /*is non object*/ 04959 << Callee->getSourceRange();4960 return ExprError();4961 }4962 4963 // Inspect the first argument of the atomic builtin. This should always be4964 // a pointer type, whose element is an integral scalar or pointer type.4965 // Because it is a pointer type, we don't have to worry about any implicit4966 // casts here.4967 // FIXME: We don't allow floating point scalars as input.4968 Expr *FirstArg = TheCall->getArg(0);4969 ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg);4970 if (FirstArgResult.isInvalid())4971 return ExprError();4972 FirstArg = FirstArgResult.get();4973 TheCall->setArg(0, FirstArg);4974 4975 const PointerType *pointerType = FirstArg->getType()->getAs<PointerType>();4976 if (!pointerType) {4977 Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer)4978 << FirstArg->getType() << 0 << FirstArg->getSourceRange();4979 return ExprError();4980 }4981 4982 QualType ValType = pointerType->getPointeeType();4983 if (!ValType->isIntegerType() && !ValType->isAnyPointerType() &&4984 !ValType->isBlockPointerType()) {4985 Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)4986 << FirstArg->getType() << 0 << FirstArg->getSourceRange();4987 return ExprError();4988 }4989 PointerAuthQualifier PointerAuth = ValType.getPointerAuth();4990 if (PointerAuth && PointerAuth.isAddressDiscriminated()) {4991 Diag(FirstArg->getBeginLoc(),4992 diag::err_atomic_op_needs_non_address_discriminated_pointer)4993 << 1 << ValType << FirstArg->getSourceRange();4994 return ExprError();4995 }4996 4997 if (ValType.isConstQualified()) {4998 Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_cannot_be_const)4999 << FirstArg->getType() << FirstArg->getSourceRange();5000 return ExprError();5001 }5002 5003 switch (ValType.getObjCLifetime()) {5004 case Qualifiers::OCL_None:5005 case Qualifiers::OCL_ExplicitNone:5006 // okay5007 break;5008 5009 case Qualifiers::OCL_Weak:5010 case Qualifiers::OCL_Strong:5011 case Qualifiers::OCL_Autoreleasing:5012 Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership)5013 << ValType << FirstArg->getSourceRange();5014 return ExprError();5015 }5016 5017 // Strip any qualifiers off ValType.5018 ValType = ValType.getUnqualifiedType();5019 5020 // The majority of builtins return a value, but a few have special return5021 // types, so allow them to override appropriately below.5022 QualType ResultType = ValType;5023 5024 // We need to figure out which concrete builtin this maps onto. For example,5025 // __sync_fetch_and_add with a 2 byte object turns into5026 // __sync_fetch_and_add_2.5027#define BUILTIN_ROW(x) \5028 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \5029 Builtin::BI##x##_8, Builtin::BI##x##_16 }5030 5031 static const unsigned BuiltinIndices[][5] = {5032 BUILTIN_ROW(__sync_fetch_and_add),5033 BUILTIN_ROW(__sync_fetch_and_sub),5034 BUILTIN_ROW(__sync_fetch_and_or),5035 BUILTIN_ROW(__sync_fetch_and_and),5036 BUILTIN_ROW(__sync_fetch_and_xor),5037 BUILTIN_ROW(__sync_fetch_and_nand),5038 5039 BUILTIN_ROW(__sync_add_and_fetch),5040 BUILTIN_ROW(__sync_sub_and_fetch),5041 BUILTIN_ROW(__sync_and_and_fetch),5042 BUILTIN_ROW(__sync_or_and_fetch),5043 BUILTIN_ROW(__sync_xor_and_fetch),5044 BUILTIN_ROW(__sync_nand_and_fetch),5045 5046 BUILTIN_ROW(__sync_val_compare_and_swap),5047 BUILTIN_ROW(__sync_bool_compare_and_swap),5048 BUILTIN_ROW(__sync_lock_test_and_set),5049 BUILTIN_ROW(__sync_lock_release),5050 BUILTIN_ROW(__sync_swap)5051 };5052#undef BUILTIN_ROW5053 5054 // Determine the index of the size.5055 unsigned SizeIndex;5056 switch (Context.getTypeSizeInChars(ValType).getQuantity()) {5057 case 1: SizeIndex = 0; break;5058 case 2: SizeIndex = 1; break;5059 case 4: SizeIndex = 2; break;5060 case 8: SizeIndex = 3; break;5061 case 16: SizeIndex = 4; break;5062 default:5063 Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_pointer_size)5064 << FirstArg->getType() << FirstArg->getSourceRange();5065 return ExprError();5066 }5067 5068 // Each of these builtins has one pointer argument, followed by some number of5069 // values (0, 1 or 2) followed by a potentially empty varags list of stuff5070 // that we ignore. Find out which row of BuiltinIndices to read from as well5071 // as the number of fixed args.5072 unsigned BuiltinID = FDecl->getBuiltinID();5073 unsigned BuiltinIndex, NumFixed = 1;5074 bool WarnAboutSemanticsChange = false;5075 switch (BuiltinID) {5076 default: llvm_unreachable("Unknown overloaded atomic builtin!");5077 case Builtin::BI__sync_fetch_and_add:5078 case Builtin::BI__sync_fetch_and_add_1:5079 case Builtin::BI__sync_fetch_and_add_2:5080 case Builtin::BI__sync_fetch_and_add_4:5081 case Builtin::BI__sync_fetch_and_add_8:5082 case Builtin::BI__sync_fetch_and_add_16:5083 BuiltinIndex = 0;5084 break;5085 5086 case Builtin::BI__sync_fetch_and_sub:5087 case Builtin::BI__sync_fetch_and_sub_1:5088 case Builtin::BI__sync_fetch_and_sub_2:5089 case Builtin::BI__sync_fetch_and_sub_4:5090 case Builtin::BI__sync_fetch_and_sub_8:5091 case Builtin::BI__sync_fetch_and_sub_16:5092 BuiltinIndex = 1;5093 break;5094 5095 case Builtin::BI__sync_fetch_and_or:5096 case Builtin::BI__sync_fetch_and_or_1:5097 case Builtin::BI__sync_fetch_and_or_2:5098 case Builtin::BI__sync_fetch_and_or_4:5099 case Builtin::BI__sync_fetch_and_or_8:5100 case Builtin::BI__sync_fetch_and_or_16:5101 BuiltinIndex = 2;5102 break;5103 5104 case Builtin::BI__sync_fetch_and_and:5105 case Builtin::BI__sync_fetch_and_and_1:5106 case Builtin::BI__sync_fetch_and_and_2:5107 case Builtin::BI__sync_fetch_and_and_4:5108 case Builtin::BI__sync_fetch_and_and_8:5109 case Builtin::BI__sync_fetch_and_and_16:5110 BuiltinIndex = 3;5111 break;5112 5113 case Builtin::BI__sync_fetch_and_xor:5114 case Builtin::BI__sync_fetch_and_xor_1:5115 case Builtin::BI__sync_fetch_and_xor_2:5116 case Builtin::BI__sync_fetch_and_xor_4:5117 case Builtin::BI__sync_fetch_and_xor_8:5118 case Builtin::BI__sync_fetch_and_xor_16:5119 BuiltinIndex = 4;5120 break;5121 5122 case Builtin::BI__sync_fetch_and_nand:5123 case Builtin::BI__sync_fetch_and_nand_1:5124 case Builtin::BI__sync_fetch_and_nand_2:5125 case Builtin::BI__sync_fetch_and_nand_4:5126 case Builtin::BI__sync_fetch_and_nand_8:5127 case Builtin::BI__sync_fetch_and_nand_16:5128 BuiltinIndex = 5;5129 WarnAboutSemanticsChange = true;5130 break;5131 5132 case Builtin::BI__sync_add_and_fetch:5133 case Builtin::BI__sync_add_and_fetch_1:5134 case Builtin::BI__sync_add_and_fetch_2:5135 case Builtin::BI__sync_add_and_fetch_4:5136 case Builtin::BI__sync_add_and_fetch_8:5137 case Builtin::BI__sync_add_and_fetch_16:5138 BuiltinIndex = 6;5139 break;5140 5141 case Builtin::BI__sync_sub_and_fetch:5142 case Builtin::BI__sync_sub_and_fetch_1:5143 case Builtin::BI__sync_sub_and_fetch_2:5144 case Builtin::BI__sync_sub_and_fetch_4:5145 case Builtin::BI__sync_sub_and_fetch_8:5146 case Builtin::BI__sync_sub_and_fetch_16:5147 BuiltinIndex = 7;5148 break;5149 5150 case Builtin::BI__sync_and_and_fetch:5151 case Builtin::BI__sync_and_and_fetch_1:5152 case Builtin::BI__sync_and_and_fetch_2:5153 case Builtin::BI__sync_and_and_fetch_4:5154 case Builtin::BI__sync_and_and_fetch_8:5155 case Builtin::BI__sync_and_and_fetch_16:5156 BuiltinIndex = 8;5157 break;5158 5159 case Builtin::BI__sync_or_and_fetch:5160 case Builtin::BI__sync_or_and_fetch_1:5161 case Builtin::BI__sync_or_and_fetch_2:5162 case Builtin::BI__sync_or_and_fetch_4:5163 case Builtin::BI__sync_or_and_fetch_8:5164 case Builtin::BI__sync_or_and_fetch_16:5165 BuiltinIndex = 9;5166 break;5167 5168 case Builtin::BI__sync_xor_and_fetch:5169 case Builtin::BI__sync_xor_and_fetch_1:5170 case Builtin::BI__sync_xor_and_fetch_2:5171 case Builtin::BI__sync_xor_and_fetch_4:5172 case Builtin::BI__sync_xor_and_fetch_8:5173 case Builtin::BI__sync_xor_and_fetch_16:5174 BuiltinIndex = 10;5175 break;5176 5177 case Builtin::BI__sync_nand_and_fetch:5178 case Builtin::BI__sync_nand_and_fetch_1:5179 case Builtin::BI__sync_nand_and_fetch_2:5180 case Builtin::BI__sync_nand_and_fetch_4:5181 case Builtin::BI__sync_nand_and_fetch_8:5182 case Builtin::BI__sync_nand_and_fetch_16:5183 BuiltinIndex = 11;5184 WarnAboutSemanticsChange = true;5185 break;5186 5187 case Builtin::BI__sync_val_compare_and_swap:5188 case Builtin::BI__sync_val_compare_and_swap_1:5189 case Builtin::BI__sync_val_compare_and_swap_2:5190 case Builtin::BI__sync_val_compare_and_swap_4:5191 case Builtin::BI__sync_val_compare_and_swap_8:5192 case Builtin::BI__sync_val_compare_and_swap_16:5193 BuiltinIndex = 12;5194 NumFixed = 2;5195 break;5196 5197 case Builtin::BI__sync_bool_compare_and_swap:5198 case Builtin::BI__sync_bool_compare_and_swap_1:5199 case Builtin::BI__sync_bool_compare_and_swap_2:5200 case Builtin::BI__sync_bool_compare_and_swap_4:5201 case Builtin::BI__sync_bool_compare_and_swap_8:5202 case Builtin::BI__sync_bool_compare_and_swap_16:5203 BuiltinIndex = 13;5204 NumFixed = 2;5205 ResultType = Context.BoolTy;5206 break;5207 5208 case Builtin::BI__sync_lock_test_and_set:5209 case Builtin::BI__sync_lock_test_and_set_1:5210 case Builtin::BI__sync_lock_test_and_set_2:5211 case Builtin::BI__sync_lock_test_and_set_4:5212 case Builtin::BI__sync_lock_test_and_set_8:5213 case Builtin::BI__sync_lock_test_and_set_16:5214 BuiltinIndex = 14;5215 break;5216 5217 case Builtin::BI__sync_lock_release:5218 case Builtin::BI__sync_lock_release_1:5219 case Builtin::BI__sync_lock_release_2:5220 case Builtin::BI__sync_lock_release_4:5221 case Builtin::BI__sync_lock_release_8:5222 case Builtin::BI__sync_lock_release_16:5223 BuiltinIndex = 15;5224 NumFixed = 0;5225 ResultType = Context.VoidTy;5226 break;5227 5228 case Builtin::BI__sync_swap:5229 case Builtin::BI__sync_swap_1:5230 case Builtin::BI__sync_swap_2:5231 case Builtin::BI__sync_swap_4:5232 case Builtin::BI__sync_swap_8:5233 case Builtin::BI__sync_swap_16:5234 BuiltinIndex = 16;5235 break;5236 }5237 5238 // Now that we know how many fixed arguments we expect, first check that we5239 // have at least that many.5240 if (TheCall->getNumArgs() < 1+NumFixed) {5241 Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)5242 << 0 << 1 + NumFixed << TheCall->getNumArgs() << /*is non object*/ 05243 << Callee->getSourceRange();5244 return ExprError();5245 }5246 5247 Diag(TheCall->getEndLoc(), diag::warn_atomic_implicit_seq_cst)5248 << Callee->getSourceRange();5249 5250 if (WarnAboutSemanticsChange) {5251 Diag(TheCall->getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)5252 << Callee->getSourceRange();5253 }5254 5255 // Get the decl for the concrete builtin from this, we can tell what the5256 // concrete integer type we should convert to is.5257 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];5258 std::string NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);5259 FunctionDecl *NewBuiltinDecl;5260 if (NewBuiltinID == BuiltinID)5261 NewBuiltinDecl = FDecl;5262 else {5263 // Perform builtin lookup to avoid redeclaring it.5264 DeclarationName DN(&Context.Idents.get(NewBuiltinName));5265 LookupResult Res(*this, DN, DRE->getBeginLoc(), LookupOrdinaryName);5266 LookupName(Res, TUScope, /*AllowBuiltinCreation=*/true);5267 assert(Res.getFoundDecl());5268 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());5269 if (!NewBuiltinDecl)5270 return ExprError();5271 }5272 5273 // The first argument --- the pointer --- has a fixed type; we5274 // deduce the types of the rest of the arguments accordingly. Walk5275 // the remaining arguments, converting them to the deduced value type.5276 for (unsigned i = 0; i != NumFixed; ++i) {5277 ExprResult Arg = TheCall->getArg(i+1);5278 5279 // GCC does an implicit conversion to the pointer or integer ValType. This5280 // can fail in some cases (1i -> int**), check for this error case now.5281 // Initialize the argument.5282 InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,5283 ValType, /*consume*/ false);5284 Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);5285 if (Arg.isInvalid())5286 return ExprError();5287 5288 // Okay, we have something that *can* be converted to the right type. Check5289 // to see if there is a potentially weird extension going on here. This can5290 // happen when you do an atomic operation on something like an char* and5291 // pass in 42. The 42 gets converted to char. This is even more strange5292 // for things like 45.123 -> char, etc.5293 // FIXME: Do this check.5294 TheCall->setArg(i+1, Arg.get());5295 }5296 5297 // Create a new DeclRefExpr to refer to the new decl.5298 DeclRefExpr *NewDRE = DeclRefExpr::Create(5299 Context, DRE->getQualifierLoc(), SourceLocation(), NewBuiltinDecl,5300 /*enclosing*/ false, DRE->getLocation(), Context.BuiltinFnTy,5301 DRE->getValueKind(), nullptr, nullptr, DRE->isNonOdrUse());5302 5303 // Set the callee in the CallExpr.5304 // FIXME: This loses syntactic information.5305 QualType CalleePtrTy = Context.getPointerType(NewBuiltinDecl->getType());5306 ExprResult PromotedCall = ImpCastExprToType(NewDRE, CalleePtrTy,5307 CK_BuiltinFnToFnPtr);5308 TheCall->setCallee(PromotedCall.get());5309 5310 // Change the result type of the call to match the original value type. This5311 // is arbitrary, but the codegen for these builtins ins design to handle it5312 // gracefully.5313 TheCall->setType(ResultType);5314 5315 // Prohibit problematic uses of bit-precise integer types with atomic5316 // builtins. The arguments would have already been converted to the first5317 // argument's type, so only need to check the first argument.5318 const auto *BitIntValType = ValType->getAs<BitIntType>();5319 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {5320 Diag(FirstArg->getExprLoc(), diag::err_atomic_builtin_ext_int_size);5321 return ExprError();5322 }5323 5324 return TheCallResult;5325}5326 5327ExprResult Sema::BuiltinNontemporalOverloaded(ExprResult TheCallResult) {5328 CallExpr *TheCall = (CallExpr *)TheCallResult.get();5329 DeclRefExpr *DRE =5330 cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());5331 FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());5332 unsigned BuiltinID = FDecl->getBuiltinID();5333 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||5334 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&5335 "Unexpected nontemporal load/store builtin!");5336 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;5337 unsigned numArgs = isStore ? 2 : 1;5338 5339 // Ensure that we have the proper number of arguments.5340 if (checkArgCount(TheCall, numArgs))5341 return ExprError();5342 5343 // Inspect the last argument of the nontemporal builtin. This should always5344 // be a pointer type, from which we imply the type of the memory access.5345 // Because it is a pointer type, we don't have to worry about any implicit5346 // casts here.5347 Expr *PointerArg = TheCall->getArg(numArgs - 1);5348 ExprResult PointerArgResult =5349 DefaultFunctionArrayLvalueConversion(PointerArg);5350 5351 if (PointerArgResult.isInvalid())5352 return ExprError();5353 PointerArg = PointerArgResult.get();5354 TheCall->setArg(numArgs - 1, PointerArg);5355 5356 const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>();5357 if (!pointerType) {5358 Diag(DRE->getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)5359 << PointerArg->getType() << PointerArg->getSourceRange();5360 return ExprError();5361 }5362 5363 QualType ValType = pointerType->getPointeeType();5364 5365 // Strip any qualifiers off ValType.5366 ValType = ValType.getUnqualifiedType();5367 if (!ValType->isIntegerType() && !ValType->isAnyPointerType() &&5368 !ValType->isBlockPointerType() && !ValType->isFloatingType() &&5369 !ValType->isVectorType()) {5370 Diag(DRE->getBeginLoc(),5371 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)5372 << PointerArg->getType() << PointerArg->getSourceRange();5373 return ExprError();5374 }5375 5376 if (!isStore) {5377 TheCall->setType(ValType);5378 return TheCallResult;5379 }5380 5381 ExprResult ValArg = TheCall->getArg(0);5382 InitializedEntity Entity = InitializedEntity::InitializeParameter(5383 Context, ValType, /*consume*/ false);5384 ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg);5385 if (ValArg.isInvalid())5386 return ExprError();5387 5388 TheCall->setArg(0, ValArg.get());5389 TheCall->setType(Context.VoidTy);5390 return TheCallResult;5391}5392 5393/// CheckObjCString - Checks that the format string argument to the os_log()5394/// and os_trace() functions is correct, and converts it to const char *.5395ExprResult Sema::CheckOSLogFormatStringArg(Expr *Arg) {5396 Arg = Arg->IgnoreParenCasts();5397 auto *Literal = dyn_cast<StringLiteral>(Arg);5398 if (!Literal) {5399 if (auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {5400 Literal = ObjcLiteral->getString();5401 }5402 }5403 5404 if (!Literal || (!Literal->isOrdinary() && !Literal->isUTF8())) {5405 return ExprError(5406 Diag(Arg->getBeginLoc(), diag::err_os_log_format_not_string_constant)5407 << Arg->getSourceRange());5408 }5409 5410 ExprResult Result(Literal);5411 QualType ResultTy = Context.getPointerType(Context.CharTy.withConst());5412 InitializedEntity Entity =5413 InitializedEntity::InitializeParameter(Context, ResultTy, false);5414 Result = PerformCopyInitialization(Entity, SourceLocation(), Result);5415 return Result;5416}5417 5418/// Check that the user is calling the appropriate va_start builtin for the5419/// target and calling convention.5420static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) {5421 const llvm::Triple &TT = S.Context.getTargetInfo().getTriple();5422 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;5423 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||5424 TT.getArch() == llvm::Triple::aarch64_32);5425 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();5426 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;5427 if (IsX64 || IsAArch64) {5428 CallingConv CC = CC_C;5429 if (const FunctionDecl *FD = S.getCurFunctionDecl())5430 CC = FD->getType()->castAs<FunctionType>()->getCallConv();5431 if (IsMSVAStart) {5432 // Don't allow this in System V ABI functions.5433 if (CC == CC_X86_64SysV || (!IsWindowsOrUEFI && CC != CC_Win64))5434 return S.Diag(Fn->getBeginLoc(),5435 diag::err_ms_va_start_used_in_sysv_function);5436 } else {5437 // On x86-64/AArch64 Unix, don't allow this in Win64 ABI functions.5438 // On x64 Windows, don't allow this in System V ABI functions.5439 // (Yes, that means there's no corresponding way to support variadic5440 // System V ABI functions on Windows.)5441 if ((IsWindowsOrUEFI && CC == CC_X86_64SysV) ||5442 (!IsWindowsOrUEFI && CC == CC_Win64))5443 return S.Diag(Fn->getBeginLoc(),5444 diag::err_va_start_used_in_wrong_abi_function)5445 << !IsWindowsOrUEFI;5446 }5447 return false;5448 }5449 5450 if (IsMSVAStart)5451 return S.Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);5452 return false;5453}5454 5455static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn,5456 ParmVarDecl **LastParam = nullptr) {5457 // Determine whether the current function, block, or obj-c method is variadic5458 // and get its parameter list.5459 bool IsVariadic = false;5460 ArrayRef<ParmVarDecl *> Params;5461 DeclContext *Caller = S.CurContext;5462 if (auto *Block = dyn_cast<BlockDecl>(Caller)) {5463 IsVariadic = Block->isVariadic();5464 Params = Block->parameters();5465 } else if (auto *FD = dyn_cast<FunctionDecl>(Caller)) {5466 IsVariadic = FD->isVariadic();5467 Params = FD->parameters();5468 } else if (auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {5469 IsVariadic = MD->isVariadic();5470 // FIXME: This isn't correct for methods (results in bogus warning).5471 Params = MD->parameters();5472 } else if (isa<CapturedDecl>(Caller)) {5473 // We don't support va_start in a CapturedDecl.5474 S.Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);5475 return true;5476 } else {5477 // This must be some other declcontext that parses exprs.5478 S.Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);5479 return true;5480 }5481 5482 if (!IsVariadic) {5483 S.Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);5484 return true;5485 }5486 5487 if (LastParam)5488 *LastParam = Params.empty() ? nullptr : Params.back();5489 5490 return false;5491}5492 5493bool Sema::BuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {5494 Expr *Fn = TheCall->getCallee();5495 if (checkVAStartABI(*this, BuiltinID, Fn))5496 return true;5497 5498 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {5499 // This builtin requires one argument (the va_list), allows two arguments,5500 // but diagnoses more than two arguments. e.g.,5501 // __builtin_c23_va_start(); // error5502 // __builtin_c23_va_start(list); // ok5503 // __builtin_c23_va_start(list, param); // ok5504 // __builtin_c23_va_start(list, anything, anything); // error5505 // This differs from the GCC behavior in that they accept the last case5506 // with a warning, but it doesn't seem like a useful behavior to allow.5507 if (checkArgCountRange(TheCall, 1, 2))5508 return true;5509 } else {5510 // In C23 mode, va_start only needs one argument. However, the builtin still5511 // requires two arguments (which matches the behavior of the GCC builtin),5512 // <stdarg.h> passes `0` as the second argument in C23 mode.5513 if (checkArgCount(TheCall, 2))5514 return true;5515 }5516 5517 // Type-check the first argument normally.5518 if (checkBuiltinArgument(*this, TheCall, 0))5519 return true;5520 5521 // Check that the current function is variadic, and get its last parameter.5522 ParmVarDecl *LastParam;5523 if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))5524 return true;5525 5526 // Verify that the second argument to the builtin is the last non-variadic5527 // argument of the current function or method. In C23 mode, if the call is5528 // not to __builtin_c23_va_start, and the second argument is an integer5529 // constant expression with value 0, then we don't bother with this check.5530 // For __builtin_c23_va_start, we only perform the check for the second5531 // argument being the last argument to the current function if there is a5532 // second argument present.5533 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&5534 TheCall->getNumArgs() < 2) {5535 Diag(TheCall->getExprLoc(), diag::warn_c17_compat_va_start_one_arg);5536 return false;5537 }5538 5539 const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();5540 if (std::optional<llvm::APSInt> Val =5541 TheCall->getArg(1)->getIntegerConstantExpr(Context);5542 Val && LangOpts.C23 && *Val == 0 &&5543 BuiltinID != Builtin::BI__builtin_c23_va_start) {5544 Diag(TheCall->getExprLoc(), diag::warn_c17_compat_va_start_one_arg);5545 return false;5546 }5547 5548 // These are valid if SecondArgIsLastNonVariadicArgument is false after the5549 // next block.5550 QualType Type;5551 SourceLocation ParamLoc;5552 bool IsCRegister = false;5553 bool SecondArgIsLastNonVariadicArgument = false;5554 if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {5555 if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {5556 SecondArgIsLastNonVariadicArgument = PV == LastParam;5557 5558 Type = PV->getType();5559 ParamLoc = PV->getLocation();5560 IsCRegister =5561 PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;5562 }5563 }5564 5565 if (!SecondArgIsLastNonVariadicArgument)5566 Diag(TheCall->getArg(1)->getBeginLoc(),5567 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);5568 else if (IsCRegister || Type->isReferenceType() ||5569 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {5570 // Promotable integers are UB, but enumerations need a bit of5571 // extra checking to see what their promotable type actually is.5572 if (!Context.isPromotableIntegerType(Type))5573 return false;5574 const auto *ED = Type->getAsEnumDecl();5575 if (!ED)5576 return true;5577 return !Context.typesAreCompatible(ED->getPromotionType(), Type);5578 }()) {5579 unsigned Reason = 0;5580 if (Type->isReferenceType()) Reason = 1;5581 else if (IsCRegister) Reason = 2;5582 Diag(Arg->getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;5583 Diag(ParamLoc, diag::note_parameter_type) << Type;5584 }5585 5586 return false;5587}5588 5589bool Sema::BuiltinVAStartARMMicrosoft(CallExpr *Call) {5590 auto IsSuitablyTypedFormatArgument = [this](const Expr *Arg) -> bool {5591 const LangOptions &LO = getLangOpts();5592 5593 if (LO.CPlusPlus)5594 return Arg->getType()5595 .getCanonicalType()5596 .getTypePtr()5597 ->getPointeeType()5598 .withoutLocalFastQualifiers() == Context.CharTy;5599 5600 // In C, allow aliasing through `char *`, this is required for AArch64 at5601 // least.5602 return true;5603 };5604 5605 // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,5606 // const char *named_addr);5607 5608 Expr *Func = Call->getCallee();5609 5610 if (Call->getNumArgs() < 3)5611 return Diag(Call->getEndLoc(),5612 diag::err_typecheck_call_too_few_args_at_least)5613 << 0 /*function call*/ << 3 << Call->getNumArgs()5614 << /*is non object*/ 0;5615 5616 // Type-check the first argument normally.5617 if (checkBuiltinArgument(*this, Call, 0))5618 return true;5619 5620 // Check that the current function is variadic.5621 if (checkVAStartIsInVariadicFunction(*this, Func))5622 return true;5623 5624 // __va_start on Windows does not validate the parameter qualifiers5625 5626 const Expr *Arg1 = Call->getArg(1)->IgnoreParens();5627 const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();5628 5629 const Expr *Arg2 = Call->getArg(2)->IgnoreParens();5630 const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();5631 5632 const QualType &ConstCharPtrTy =5633 Context.getPointerType(Context.CharTy.withConst());5634 if (!Arg1Ty->isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))5635 Diag(Arg1->getBeginLoc(), diag::err_typecheck_convert_incompatible)5636 << Arg1->getType() << ConstCharPtrTy << 1 /* different class */5637 << 0 /* qualifier difference */5638 << 3 /* parameter mismatch */5639 << 2 << Arg1->getType() << ConstCharPtrTy;5640 5641 const QualType SizeTy = Context.getSizeType();5642 if (!Context.hasSameType(5643 Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers(),5644 SizeTy))5645 Diag(Arg2->getBeginLoc(), diag::err_typecheck_convert_incompatible)5646 << Arg2->getType() << SizeTy << 1 /* different class */5647 << 0 /* qualifier difference */5648 << 3 /* parameter mismatch */5649 << 3 << Arg2->getType() << SizeTy;5650 5651 return false;5652}5653 5654bool Sema::BuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) {5655 if (checkArgCount(TheCall, 2))5656 return true;5657 5658 if (BuiltinID == Builtin::BI__builtin_isunordered &&5659 TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs())5660 Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)5661 << 1 << 0 << TheCall->getSourceRange();5662 5663 ExprResult OrigArg0 = TheCall->getArg(0);5664 ExprResult OrigArg1 = TheCall->getArg(1);5665 5666 // Do standard promotions between the two arguments, returning their common5667 // type.5668 QualType Res = UsualArithmeticConversions(5669 OrigArg0, OrigArg1, TheCall->getExprLoc(), ArithConvKind::Comparison);5670 if (OrigArg0.isInvalid() || OrigArg1.isInvalid())5671 return true;5672 5673 // Make sure any conversions are pushed back into the call; this is5674 // type safe since unordered compare builtins are declared as "_Bool5675 // foo(...)".5676 TheCall->setArg(0, OrigArg0.get());5677 TheCall->setArg(1, OrigArg1.get());5678 5679 if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())5680 return false;5681 5682 // If the common type isn't a real floating type, then the arguments were5683 // invalid for this operation.5684 if (Res.isNull() || !Res->isRealFloatingType())5685 return Diag(OrigArg0.get()->getBeginLoc(),5686 diag::err_typecheck_call_invalid_ordered_compare)5687 << OrigArg0.get()->getType() << OrigArg1.get()->getType()5688 << SourceRange(OrigArg0.get()->getBeginLoc(),5689 OrigArg1.get()->getEndLoc());5690 5691 return false;5692}5693 5694bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs,5695 unsigned BuiltinID) {5696 if (checkArgCount(TheCall, NumArgs))5697 return true;5698 5699 FPOptions FPO = TheCall->getFPFeaturesInEffect(getLangOpts());5700 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||5701 BuiltinID == Builtin::BI__builtin_isinf ||5702 BuiltinID == Builtin::BI__builtin_isinf_sign))5703 Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)5704 << 0 << 0 << TheCall->getSourceRange();5705 5706 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||5707 BuiltinID == Builtin::BI__builtin_isunordered))5708 Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)5709 << 1 << 0 << TheCall->getSourceRange();5710 5711 bool IsFPClass = NumArgs == 2;5712 5713 // Find out position of floating-point argument.5714 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;5715 5716 // We can count on all parameters preceding the floating-point just being int.5717 // Try all of those.5718 for (unsigned i = 0; i < FPArgNo; ++i) {5719 Expr *Arg = TheCall->getArg(i);5720 5721 if (Arg->isTypeDependent())5722 return false;5723 5724 ExprResult Res = PerformImplicitConversion(Arg, Context.IntTy,5725 AssignmentAction::Passing);5726 5727 if (Res.isInvalid())5728 return true;5729 TheCall->setArg(i, Res.get());5730 }5731 5732 Expr *OrigArg = TheCall->getArg(FPArgNo);5733 5734 if (OrigArg->isTypeDependent())5735 return false;5736 5737 // Usual Unary Conversions will convert half to float, which we want for5738 // machines that use fp16 conversion intrinsics. Else, we wnat to leave the5739 // type how it is, but do normal L->Rvalue conversions.5740 if (Context.getTargetInfo().useFP16ConversionIntrinsics()) {5741 ExprResult Res = UsualUnaryConversions(OrigArg);5742 5743 if (!Res.isUsable())5744 return true;5745 OrigArg = Res.get();5746 } else {5747 ExprResult Res = DefaultFunctionArrayLvalueConversion(OrigArg);5748 5749 if (!Res.isUsable())5750 return true;5751 OrigArg = Res.get();5752 }5753 TheCall->setArg(FPArgNo, OrigArg);5754 5755 QualType VectorResultTy;5756 QualType ElementTy = OrigArg->getType();5757 // TODO: When all classification function are implemented with is_fpclass,5758 // vector argument can be supported in all of them.5759 if (ElementTy->isVectorType() && IsFPClass) {5760 VectorResultTy = GetSignedVectorType(ElementTy);5761 ElementTy = ElementTy->castAs<VectorType>()->getElementType();5762 }5763 5764 // This operation requires a non-_Complex floating-point number.5765 if (!ElementTy->isRealFloatingType())5766 return Diag(OrigArg->getBeginLoc(),5767 diag::err_typecheck_call_invalid_unary_fp)5768 << OrigArg->getType() << OrigArg->getSourceRange();5769 5770 // __builtin_isfpclass has integer parameter that specify test mask. It is5771 // passed in (...), so it should be analyzed completely here.5772 if (IsFPClass)5773 if (BuiltinConstantArgRange(TheCall, 1, 0, llvm::fcAllFlags))5774 return true;5775 5776 // TODO: enable this code to all classification functions.5777 if (IsFPClass) {5778 QualType ResultTy;5779 if (!VectorResultTy.isNull())5780 ResultTy = VectorResultTy;5781 else5782 ResultTy = Context.IntTy;5783 TheCall->setType(ResultTy);5784 }5785 5786 return false;5787}5788 5789bool Sema::BuiltinComplex(CallExpr *TheCall) {5790 if (checkArgCount(TheCall, 2))5791 return true;5792 5793 bool Dependent = false;5794 for (unsigned I = 0; I != 2; ++I) {5795 Expr *Arg = TheCall->getArg(I);5796 QualType T = Arg->getType();5797 if (T->isDependentType()) {5798 Dependent = true;5799 continue;5800 }5801 5802 // Despite supporting _Complex int, GCC requires a real floating point type5803 // for the operands of __builtin_complex.5804 if (!T->isRealFloatingType()) {5805 return Diag(Arg->getBeginLoc(), diag::err_typecheck_call_requires_real_fp)5806 << Arg->getType() << Arg->getSourceRange();5807 }5808 5809 ExprResult Converted = DefaultLvalueConversion(Arg);5810 if (Converted.isInvalid())5811 return true;5812 TheCall->setArg(I, Converted.get());5813 }5814 5815 if (Dependent) {5816 TheCall->setType(Context.DependentTy);5817 return false;5818 }5819 5820 Expr *Real = TheCall->getArg(0);5821 Expr *Imag = TheCall->getArg(1);5822 if (!Context.hasSameType(Real->getType(), Imag->getType())) {5823 return Diag(Real->getBeginLoc(),5824 diag::err_typecheck_call_different_arg_types)5825 << Real->getType() << Imag->getType()5826 << Real->getSourceRange() << Imag->getSourceRange();5827 }5828 5829 TheCall->setType(Context.getComplexType(Real->getType()));5830 return false;5831}5832 5833/// BuiltinShuffleVector - Handle __builtin_shufflevector.5834// This is declared to take (...), so we have to check everything.5835ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {5836 unsigned NumArgs = TheCall->getNumArgs();5837 if (NumArgs < 2)5838 return ExprError(Diag(TheCall->getEndLoc(),5839 diag::err_typecheck_call_too_few_args_at_least)5840 << 0 /*function call*/ << 2 << NumArgs5841 << /*is non object*/ 0 << TheCall->getSourceRange());5842 5843 // Determine which of the following types of shufflevector we're checking:5844 // 1) unary, vector mask: (lhs, mask)5845 // 2) binary, scalar mask: (lhs, rhs, index, ..., index)5846 QualType ResType = TheCall->getArg(0)->getType();5847 unsigned NumElements = 0;5848 5849 if (!TheCall->getArg(0)->isTypeDependent() &&5850 !TheCall->getArg(1)->isTypeDependent()) {5851 QualType LHSType = TheCall->getArg(0)->getType();5852 QualType RHSType = TheCall->getArg(1)->getType();5853 5854 if (!LHSType->isVectorType() || !RHSType->isVectorType())5855 return ExprError(5856 Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector)5857 << TheCall->getDirectCallee() << /*isMoreThanTwoArgs*/ false5858 << SourceRange(TheCall->getArg(0)->getBeginLoc(),5859 TheCall->getArg(1)->getEndLoc()));5860 5861 NumElements = LHSType->castAs<VectorType>()->getNumElements();5862 unsigned NumResElements = NumArgs - 2;5863 5864 // Check to see if we have a call with 2 vector arguments, the unary shuffle5865 // with mask. If so, verify that RHS is an integer vector type with the5866 // same number of elts as lhs.5867 if (NumArgs == 2) {5868 if (!RHSType->hasIntegerRepresentation() ||5869 RHSType->castAs<VectorType>()->getNumElements() != NumElements)5870 return ExprError(Diag(TheCall->getBeginLoc(),5871 diag::err_vec_builtin_incompatible_vector)5872 << TheCall->getDirectCallee()5873 << /*isMoreThanTwoArgs*/ false5874 << SourceRange(TheCall->getArg(1)->getBeginLoc(),5875 TheCall->getArg(1)->getEndLoc()));5876 } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {5877 return ExprError(Diag(TheCall->getBeginLoc(),5878 diag::err_vec_builtin_incompatible_vector)5879 << TheCall->getDirectCallee()5880 << /*isMoreThanTwoArgs*/ false5881 << SourceRange(TheCall->getArg(0)->getBeginLoc(),5882 TheCall->getArg(1)->getEndLoc()));5883 } else if (NumElements != NumResElements) {5884 QualType EltType = LHSType->castAs<VectorType>()->getElementType();5885 ResType = ResType->isExtVectorType()5886 ? Context.getExtVectorType(EltType, NumResElements)5887 : Context.getVectorType(EltType, NumResElements,5888 VectorKind::Generic);5889 }5890 }5891 5892 for (unsigned I = 2; I != NumArgs; ++I) {5893 Expr *Arg = TheCall->getArg(I);5894 if (Arg->isTypeDependent() || Arg->isValueDependent())5895 continue;5896 5897 std::optional<llvm::APSInt> Result = Arg->getIntegerConstantExpr(Context);5898 if (!Result)5899 return ExprError(Diag(TheCall->getBeginLoc(),5900 diag::err_shufflevector_nonconstant_argument)5901 << Arg->getSourceRange());5902 5903 // Allow -1 which will be translated to undef in the IR.5904 if (Result->isSigned() && Result->isAllOnes())5905 ;5906 else if (Result->getActiveBits() > 64 ||5907 Result->getZExtValue() >= NumElements * 2)5908 return ExprError(Diag(TheCall->getBeginLoc(),5909 diag::err_shufflevector_argument_too_large)5910 << Arg->getSourceRange());5911 5912 TheCall->setArg(I, ConstantExpr::Create(Context, Arg, APValue(*Result)));5913 }5914 5915 auto *Result = new (Context) ShuffleVectorExpr(5916 Context, ArrayRef(TheCall->getArgs(), NumArgs), ResType,5917 TheCall->getCallee()->getBeginLoc(), TheCall->getRParenLoc());5918 5919 // All moved to Result.5920 TheCall->shrinkNumArgs(0);5921 return Result;5922}5923 5924ExprResult Sema::ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,5925 SourceLocation BuiltinLoc,5926 SourceLocation RParenLoc) {5927 ExprValueKind VK = VK_PRValue;5928 ExprObjectKind OK = OK_Ordinary;5929 QualType DstTy = TInfo->getType();5930 QualType SrcTy = E->getType();5931 5932 if (!SrcTy->isVectorType() && !SrcTy->isDependentType())5933 return ExprError(Diag(BuiltinLoc,5934 diag::err_convertvector_non_vector)5935 << E->getSourceRange());5936 if (!DstTy->isVectorType() && !DstTy->isDependentType())5937 return ExprError(Diag(BuiltinLoc, diag::err_builtin_non_vector_type)5938 << "second"5939 << "__builtin_convertvector");5940 5941 if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {5942 unsigned SrcElts = SrcTy->castAs<VectorType>()->getNumElements();5943 unsigned DstElts = DstTy->castAs<VectorType>()->getNumElements();5944 if (SrcElts != DstElts)5945 return ExprError(Diag(BuiltinLoc,5946 diag::err_convertvector_incompatible_vector)5947 << E->getSourceRange());5948 }5949 5950 return ConvertVectorExpr::Create(Context, E, TInfo, DstTy, VK, OK, BuiltinLoc,5951 RParenLoc, CurFPFeatureOverrides());5952}5953 5954bool Sema::BuiltinPrefetch(CallExpr *TheCall) {5955 unsigned NumArgs = TheCall->getNumArgs();5956 5957 if (NumArgs > 3)5958 return Diag(TheCall->getEndLoc(),5959 diag::err_typecheck_call_too_many_args_at_most)5960 << 0 /*function call*/ << 3 << NumArgs << /*is non object*/ 05961 << TheCall->getSourceRange();5962 5963 // Argument 0 is checked for us and the remaining arguments must be5964 // constant integers.5965 for (unsigned i = 1; i != NumArgs; ++i)5966 if (BuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))5967 return true;5968 5969 return false;5970}5971 5972bool Sema::BuiltinArithmeticFence(CallExpr *TheCall) {5973 if (!Context.getTargetInfo().checkArithmeticFenceSupported())5974 return Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)5975 << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());5976 if (checkArgCount(TheCall, 1))5977 return true;5978 Expr *Arg = TheCall->getArg(0);5979 if (Arg->isInstantiationDependent())5980 return false;5981 5982 QualType ArgTy = Arg->getType();5983 if (!ArgTy->hasFloatingRepresentation())5984 return Diag(TheCall->getEndLoc(), diag::err_typecheck_expect_flt_or_vector)5985 << ArgTy;5986 if (Arg->isLValue()) {5987 ExprResult FirstArg = DefaultLvalueConversion(Arg);5988 TheCall->setArg(0, FirstArg.get());5989 }5990 TheCall->setType(TheCall->getArg(0)->getType());5991 return false;5992}5993 5994bool Sema::BuiltinAssume(CallExpr *TheCall) {5995 Expr *Arg = TheCall->getArg(0);5996 if (Arg->isInstantiationDependent()) return false;5997 5998 if (Arg->HasSideEffects(Context))5999 Diag(Arg->getBeginLoc(), diag::warn_assume_side_effects)6000 << Arg->getSourceRange()6001 << cast<FunctionDecl>(TheCall->getCalleeDecl())->getIdentifier();6002 6003 return false;6004}6005 6006bool Sema::BuiltinAllocaWithAlign(CallExpr *TheCall) {6007 // The alignment must be a constant integer.6008 Expr *Arg = TheCall->getArg(1);6009 6010 // We can't check the value of a dependent argument.6011 if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {6012 if (const auto *UE =6013 dyn_cast<UnaryExprOrTypeTraitExpr>(Arg->IgnoreParenImpCasts()))6014 if (UE->getKind() == UETT_AlignOf ||6015 UE->getKind() == UETT_PreferredAlignOf)6016 Diag(TheCall->getBeginLoc(), diag::warn_alloca_align_alignof)6017 << Arg->getSourceRange();6018 6019 llvm::APSInt Result = Arg->EvaluateKnownConstInt(Context);6020 6021 if (!Result.isPowerOf2())6022 return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two)6023 << Arg->getSourceRange();6024 6025 if (Result < Context.getCharWidth())6026 return Diag(TheCall->getBeginLoc(), diag::err_alignment_too_small)6027 << (unsigned)Context.getCharWidth() << Arg->getSourceRange();6028 6029 if (Result > std::numeric_limits<int32_t>::max())6030 return Diag(TheCall->getBeginLoc(), diag::err_alignment_too_big)6031 << std::numeric_limits<int32_t>::max() << Arg->getSourceRange();6032 }6033 6034 return false;6035}6036 6037bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) {6038 if (checkArgCountRange(TheCall, 2, 3))6039 return true;6040 6041 unsigned NumArgs = TheCall->getNumArgs();6042 Expr *FirstArg = TheCall->getArg(0);6043 6044 {6045 ExprResult FirstArgResult =6046 DefaultFunctionArrayLvalueConversion(FirstArg);6047 if (!FirstArgResult.get()->getType()->isPointerType()) {6048 Diag(TheCall->getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)6049 << TheCall->getSourceRange();6050 return true;6051 }6052 TheCall->setArg(0, FirstArgResult.get());6053 }6054 6055 // The alignment must be a constant integer.6056 Expr *SecondArg = TheCall->getArg(1);6057 6058 // We can't check the value of a dependent argument.6059 if (!SecondArg->isValueDependent()) {6060 llvm::APSInt Result;6061 if (BuiltinConstantArg(TheCall, 1, Result))6062 return true;6063 6064 if (!Result.isPowerOf2())6065 return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two)6066 << SecondArg->getSourceRange();6067 6068 if (Result > Sema::MaximumAlignment)6069 Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great)6070 << SecondArg->getSourceRange() << Sema::MaximumAlignment;6071 6072 TheCall->setArg(1,6073 ConstantExpr::Create(Context, SecondArg, APValue(Result)));6074 }6075 6076 if (NumArgs > 2) {6077 Expr *ThirdArg = TheCall->getArg(2);6078 if (convertArgumentToType(*this, ThirdArg, Context.getSizeType()))6079 return true;6080 TheCall->setArg(2, ThirdArg);6081 }6082 6083 return false;6084}6085 6086bool Sema::BuiltinOSLogFormat(CallExpr *TheCall) {6087 unsigned BuiltinID =6088 cast<FunctionDecl>(TheCall->getCalleeDecl())->getBuiltinID();6089 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;6090 6091 unsigned NumArgs = TheCall->getNumArgs();6092 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;6093 if (NumArgs < NumRequiredArgs) {6094 return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args)6095 << 0 /* function call */ << NumRequiredArgs << NumArgs6096 << /*is non object*/ 0 << TheCall->getSourceRange();6097 }6098 if (NumArgs >= NumRequiredArgs + 0x100) {6099 return Diag(TheCall->getEndLoc(),6100 diag::err_typecheck_call_too_many_args_at_most)6101 << 0 /* function call */ << (NumRequiredArgs + 0xff) << NumArgs6102 << /*is non object*/ 0 << TheCall->getSourceRange();6103 }6104 unsigned i = 0;6105 6106 // For formatting call, check buffer arg.6107 if (!IsSizeCall) {6108 ExprResult Arg(TheCall->getArg(i));6109 InitializedEntity Entity = InitializedEntity::InitializeParameter(6110 Context, Context.VoidPtrTy, false);6111 Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);6112 if (Arg.isInvalid())6113 return true;6114 TheCall->setArg(i, Arg.get());6115 i++;6116 }6117 6118 // Check string literal arg.6119 unsigned FormatIdx = i;6120 {6121 ExprResult Arg = CheckOSLogFormatStringArg(TheCall->getArg(i));6122 if (Arg.isInvalid())6123 return true;6124 TheCall->setArg(i, Arg.get());6125 i++;6126 }6127 6128 // Make sure variadic args are scalar.6129 unsigned FirstDataArg = i;6130 while (i < NumArgs) {6131 ExprResult Arg = DefaultVariadicArgumentPromotion(6132 TheCall->getArg(i), VariadicCallType::Function, nullptr);6133 if (Arg.isInvalid())6134 return true;6135 CharUnits ArgSize = Context.getTypeSizeInChars(Arg.get()->getType());6136 if (ArgSize.getQuantity() >= 0x100) {6137 return Diag(Arg.get()->getEndLoc(), diag::err_os_log_argument_too_big)6138 << i << (int)ArgSize.getQuantity() << 0xff6139 << TheCall->getSourceRange();6140 }6141 TheCall->setArg(i, Arg.get());6142 i++;6143 }6144 6145 // Check formatting specifiers. NOTE: We're only doing this for the non-size6146 // call to avoid duplicate diagnostics.6147 if (!IsSizeCall) {6148 llvm::SmallBitVector CheckedVarArgs(NumArgs, false);6149 ArrayRef<const Expr *> Args(TheCall->getArgs(), TheCall->getNumArgs());6150 bool Success = CheckFormatArguments(6151 Args, FAPK_Variadic, nullptr, FormatIdx, FirstDataArg,6152 FormatStringType::OSLog, VariadicCallType::Function,6153 TheCall->getBeginLoc(), SourceRange(), CheckedVarArgs);6154 if (!Success)6155 return true;6156 }6157 6158 if (IsSizeCall) {6159 TheCall->setType(Context.getSizeType());6160 } else {6161 TheCall->setType(Context.VoidPtrTy);6162 }6163 return false;6164}6165 6166bool Sema::BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum,6167 llvm::APSInt &Result) {6168 Expr *Arg = TheCall->getArg(ArgNum);6169 6170 if (Arg->isTypeDependent() || Arg->isValueDependent())6171 return false;6172 6173 std::optional<llvm::APSInt> R = Arg->getIntegerConstantExpr(Context);6174 if (!R) {6175 auto *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());6176 auto *FDecl = cast<FunctionDecl>(DRE->getDecl());6177 return Diag(TheCall->getBeginLoc(), diag::err_constant_integer_arg_type)6178 << FDecl->getDeclName() << Arg->getSourceRange();6179 }6180 Result = *R;6181 6182 return false;6183}6184 6185bool Sema::BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low,6186 int High, bool RangeIsError) {6187 if (isConstantEvaluatedContext())6188 return false;6189 llvm::APSInt Result;6190 6191 // We can't check the value of a dependent argument.6192 Expr *Arg = TheCall->getArg(ArgNum);6193 if (Arg->isTypeDependent() || Arg->isValueDependent())6194 return false;6195 6196 // Check constant-ness first.6197 if (BuiltinConstantArg(TheCall, ArgNum, Result))6198 return true;6199 6200 if (Result.getSExtValue() < Low || Result.getSExtValue() > High) {6201 if (RangeIsError)6202 return Diag(TheCall->getBeginLoc(), diag::err_argument_invalid_range)6203 << toString(Result, 10) << Low << High << Arg->getSourceRange();6204 else6205 // Defer the warning until we know if the code will be emitted so that6206 // dead code can ignore this.6207 DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall,6208 PDiag(diag::warn_argument_invalid_range)6209 << toString(Result, 10) << Low << High6210 << Arg->getSourceRange());6211 }6212 6213 return false;6214}6215 6216bool Sema::BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum,6217 unsigned Num) {6218 llvm::APSInt Result;6219 6220 // We can't check the value of a dependent argument.6221 Expr *Arg = TheCall->getArg(ArgNum);6222 if (Arg->isTypeDependent() || Arg->isValueDependent())6223 return false;6224 6225 // Check constant-ness first.6226 if (BuiltinConstantArg(TheCall, ArgNum, Result))6227 return true;6228 6229 if (Result.getSExtValue() % Num != 0)6230 return Diag(TheCall->getBeginLoc(), diag::err_argument_not_multiple)6231 << Num << Arg->getSourceRange();6232 6233 return false;6234}6235 6236bool Sema::BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum) {6237 llvm::APSInt Result;6238 6239 // We can't check the value of a dependent argument.6240 Expr *Arg = TheCall->getArg(ArgNum);6241 if (Arg->isTypeDependent() || Arg->isValueDependent())6242 return false;6243 6244 // Check constant-ness first.6245 if (BuiltinConstantArg(TheCall, ArgNum, Result))6246 return true;6247 6248 if (Result.isPowerOf2())6249 return false;6250 6251 return Diag(TheCall->getBeginLoc(), diag::err_argument_not_power_of_2)6252 << Arg->getSourceRange();6253}6254 6255static bool IsShiftedByte(llvm::APSInt Value) {6256 if (Value.isNegative())6257 return false;6258 6259 // Check if it's a shifted byte, by shifting it down6260 while (true) {6261 // If the value fits in the bottom byte, the check passes.6262 if (Value < 0x100)6263 return true;6264 6265 // Otherwise, if the value has _any_ bits in the bottom byte, the check6266 // fails.6267 if ((Value & 0xFF) != 0)6268 return false;6269 6270 // If the bottom 8 bits are all 0, but something above that is nonzero,6271 // then shifting the value right by 8 bits won't affect whether it's a6272 // shifted byte or not. So do that, and go round again.6273 Value >>= 8;6274 }6275}6276 6277bool Sema::BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum,6278 unsigned ArgBits) {6279 llvm::APSInt Result;6280 6281 // We can't check the value of a dependent argument.6282 Expr *Arg = TheCall->getArg(ArgNum);6283 if (Arg->isTypeDependent() || Arg->isValueDependent())6284 return false;6285 6286 // Check constant-ness first.6287 if (BuiltinConstantArg(TheCall, ArgNum, Result))6288 return true;6289 6290 // Truncate to the given size.6291 Result = Result.getLoBits(ArgBits);6292 Result.setIsUnsigned(true);6293 6294 if (IsShiftedByte(Result))6295 return false;6296 6297 return Diag(TheCall->getBeginLoc(), diag::err_argument_not_shifted_byte)6298 << Arg->getSourceRange();6299}6300 6301bool Sema::BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall,6302 unsigned ArgNum,6303 unsigned ArgBits) {6304 llvm::APSInt Result;6305 6306 // We can't check the value of a dependent argument.6307 Expr *Arg = TheCall->getArg(ArgNum);6308 if (Arg->isTypeDependent() || Arg->isValueDependent())6309 return false;6310 6311 // Check constant-ness first.6312 if (BuiltinConstantArg(TheCall, ArgNum, Result))6313 return true;6314 6315 // Truncate to the given size.6316 Result = Result.getLoBits(ArgBits);6317 Result.setIsUnsigned(true);6318 6319 // Check to see if it's in either of the required forms.6320 if (IsShiftedByte(Result) ||6321 (Result > 0 && Result < 0x10000 && (Result & 0xFF) == 0xFF))6322 return false;6323 6324 return Diag(TheCall->getBeginLoc(),6325 diag::err_argument_not_shifted_byte_or_xxff)6326 << Arg->getSourceRange();6327}6328 6329bool Sema::BuiltinLongjmp(CallExpr *TheCall) {6330 if (!Context.getTargetInfo().hasSjLjLowering())6331 return Diag(TheCall->getBeginLoc(), diag::err_builtin_longjmp_unsupported)6332 << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());6333 6334 Expr *Arg = TheCall->getArg(1);6335 llvm::APSInt Result;6336 6337 // TODO: This is less than ideal. Overload this to take a value.6338 if (BuiltinConstantArg(TheCall, 1, Result))6339 return true;6340 6341 if (Result != 1)6342 return Diag(TheCall->getBeginLoc(), diag::err_builtin_longjmp_invalid_val)6343 << SourceRange(Arg->getBeginLoc(), Arg->getEndLoc());6344 6345 return false;6346}6347 6348bool Sema::BuiltinSetjmp(CallExpr *TheCall) {6349 if (!Context.getTargetInfo().hasSjLjLowering())6350 return Diag(TheCall->getBeginLoc(), diag::err_builtin_setjmp_unsupported)6351 << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());6352 return false;6353}6354 6355bool Sema::BuiltinCountedByRef(CallExpr *TheCall) {6356 if (checkArgCount(TheCall, 1))6357 return true;6358 6359 ExprResult ArgRes = UsualUnaryConversions(TheCall->getArg(0));6360 if (ArgRes.isInvalid())6361 return true;6362 6363 // For simplicity, we support only limited expressions for the argument.6364 // Specifically a pointer to a flexible array member:'ptr->array'. This6365 // allows us to reject arguments with complex casting, which really shouldn't6366 // be a huge problem.6367 const Expr *Arg = ArgRes.get()->IgnoreParenImpCasts();6368 if (!isa<PointerType>(Arg->getType()) && !Arg->getType()->isArrayType())6369 return Diag(Arg->getBeginLoc(),6370 diag::err_builtin_counted_by_ref_must_be_flex_array_member)6371 << Arg->getSourceRange();6372 6373 if (Arg->HasSideEffects(Context))6374 return Diag(Arg->getBeginLoc(),6375 diag::err_builtin_counted_by_ref_has_side_effects)6376 << Arg->getSourceRange();6377 6378 if (const auto *ME = dyn_cast<MemberExpr>(Arg)) {6379 if (!ME->isFlexibleArrayMemberLike(6380 Context, getLangOpts().getStrictFlexArraysLevel()))6381 return Diag(Arg->getBeginLoc(),6382 diag::err_builtin_counted_by_ref_must_be_flex_array_member)6383 << Arg->getSourceRange();6384 6385 if (auto *CATy =6386 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();6387 CATy && CATy->getKind() == CountAttributedType::CountedBy) {6388 const auto *FAMDecl = cast<FieldDecl>(ME->getMemberDecl());6389 if (const FieldDecl *CountFD = FAMDecl->findCountedByField()) {6390 TheCall->setType(Context.getPointerType(CountFD->getType()));6391 return false;6392 }6393 }6394 } else {6395 return Diag(Arg->getBeginLoc(),6396 diag::err_builtin_counted_by_ref_must_be_flex_array_member)6397 << Arg->getSourceRange();6398 }6399 6400 TheCall->setType(Context.getPointerType(Context.VoidTy));6401 return false;6402}6403 6404/// The result of __builtin_counted_by_ref cannot be assigned to a variable.6405/// It allows leaking and modification of bounds safety information.6406bool Sema::CheckInvalidBuiltinCountedByRef(const Expr *E,6407 BuiltinCountedByRefKind K) {6408 const CallExpr *CE =6409 E ? dyn_cast<CallExpr>(E->IgnoreParenImpCasts()) : nullptr;6410 if (!CE || CE->getBuiltinCallee() != Builtin::BI__builtin_counted_by_ref)6411 return false;6412 6413 switch (K) {6414 case BuiltinCountedByRefKind::Assignment:6415 case BuiltinCountedByRefKind::Initializer:6416 Diag(E->getExprLoc(),6417 diag::err_builtin_counted_by_ref_cannot_leak_reference)6418 << 0 << E->getSourceRange();6419 break;6420 case BuiltinCountedByRefKind::FunctionArg:6421 Diag(E->getExprLoc(),6422 diag::err_builtin_counted_by_ref_cannot_leak_reference)6423 << 1 << E->getSourceRange();6424 break;6425 case BuiltinCountedByRefKind::ReturnArg:6426 Diag(E->getExprLoc(),6427 diag::err_builtin_counted_by_ref_cannot_leak_reference)6428 << 2 << E->getSourceRange();6429 break;6430 case BuiltinCountedByRefKind::ArraySubscript:6431 Diag(E->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)6432 << 0 << E->getSourceRange();6433 break;6434 case BuiltinCountedByRefKind::BinaryExpr:6435 Diag(E->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)6436 << 1 << E->getSourceRange();6437 break;6438 }6439 6440 return true;6441}6442 6443namespace {6444 6445class UncoveredArgHandler {6446 enum { Unknown = -1, AllCovered = -2 };6447 6448 signed FirstUncoveredArg = Unknown;6449 SmallVector<const Expr *, 4> DiagnosticExprs;6450 6451public:6452 UncoveredArgHandler() = default;6453 6454 bool hasUncoveredArg() const {6455 return (FirstUncoveredArg >= 0);6456 }6457 6458 unsigned getUncoveredArg() const {6459 assert(hasUncoveredArg() && "no uncovered argument");6460 return FirstUncoveredArg;6461 }6462 6463 void setAllCovered() {6464 // A string has been found with all arguments covered, so clear out6465 // the diagnostics.6466 DiagnosticExprs.clear();6467 FirstUncoveredArg = AllCovered;6468 }6469 6470 void Update(signed NewFirstUncoveredArg, const Expr *StrExpr) {6471 assert(NewFirstUncoveredArg >= 0 && "Outside range");6472 6473 // Don't update if a previous string covers all arguments.6474 if (FirstUncoveredArg == AllCovered)6475 return;6476 6477 // UncoveredArgHandler tracks the highest uncovered argument index6478 // and with it all the strings that match this index.6479 if (NewFirstUncoveredArg == FirstUncoveredArg)6480 DiagnosticExprs.push_back(StrExpr);6481 else if (NewFirstUncoveredArg > FirstUncoveredArg) {6482 DiagnosticExprs.clear();6483 DiagnosticExprs.push_back(StrExpr);6484 FirstUncoveredArg = NewFirstUncoveredArg;6485 }6486 }6487 6488 void Diagnose(Sema &S, bool IsFunctionCall, const Expr *ArgExpr);6489};6490 6491enum StringLiteralCheckType {6492 SLCT_NotALiteral,6493 SLCT_UncheckedLiteral,6494 SLCT_CheckedLiteral6495};6496 6497} // namespace6498 6499static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend,6500 BinaryOperatorKind BinOpKind,6501 bool AddendIsRight) {6502 unsigned BitWidth = Offset.getBitWidth();6503 unsigned AddendBitWidth = Addend.getBitWidth();6504 // There might be negative interim results.6505 if (Addend.isUnsigned()) {6506 Addend = Addend.zext(++AddendBitWidth);6507 Addend.setIsSigned(true);6508 }6509 // Adjust the bit width of the APSInts.6510 if (AddendBitWidth > BitWidth) {6511 Offset = Offset.sext(AddendBitWidth);6512 BitWidth = AddendBitWidth;6513 } else if (BitWidth > AddendBitWidth) {6514 Addend = Addend.sext(BitWidth);6515 }6516 6517 bool Ov = false;6518 llvm::APSInt ResOffset = Offset;6519 if (BinOpKind == BO_Add)6520 ResOffset = Offset.sadd_ov(Addend, Ov);6521 else {6522 assert(AddendIsRight && BinOpKind == BO_Sub &&6523 "operator must be add or sub with addend on the right");6524 ResOffset = Offset.ssub_ov(Addend, Ov);6525 }6526 6527 // We add an offset to a pointer here so we should support an offset as big as6528 // possible.6529 if (Ov) {6530 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&6531 "index (intermediate) result too big");6532 Offset = Offset.sext(2 * BitWidth);6533 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);6534 return;6535 }6536 6537 Offset = ResOffset;6538}6539 6540namespace {6541 6542// This is a wrapper class around StringLiteral to support offsetted string6543// literals as format strings. It takes the offset into account when returning6544// the string and its length or the source locations to display notes correctly.6545class FormatStringLiteral {6546 const StringLiteral *FExpr;6547 int64_t Offset;6548 6549public:6550 FormatStringLiteral(const StringLiteral *fexpr, int64_t Offset = 0)6551 : FExpr(fexpr), Offset(Offset) {}6552 6553 const StringLiteral *getFormatString() const { return FExpr; }6554 6555 StringRef getString() const { return FExpr->getString().drop_front(Offset); }6556 6557 unsigned getByteLength() const {6558 return FExpr->getByteLength() - getCharByteWidth() * Offset;6559 }6560 6561 unsigned getLength() const { return FExpr->getLength() - Offset; }6562 unsigned getCharByteWidth() const { return FExpr->getCharByteWidth(); }6563 6564 StringLiteralKind getKind() const { return FExpr->getKind(); }6565 6566 QualType getType() const { return FExpr->getType(); }6567 6568 bool isAscii() const { return FExpr->isOrdinary(); }6569 bool isWide() const { return FExpr->isWide(); }6570 bool isUTF8() const { return FExpr->isUTF8(); }6571 bool isUTF16() const { return FExpr->isUTF16(); }6572 bool isUTF32() const { return FExpr->isUTF32(); }6573 bool isPascal() const { return FExpr->isPascal(); }6574 6575 SourceLocation getLocationOfByte(6576 unsigned ByteNo, const SourceManager &SM, const LangOptions &Features,6577 const TargetInfo &Target, unsigned *StartToken = nullptr,6578 unsigned *StartTokenByteOffset = nullptr) const {6579 return FExpr->getLocationOfByte(ByteNo + Offset, SM, Features, Target,6580 StartToken, StartTokenByteOffset);6581 }6582 6583 SourceLocation getBeginLoc() const LLVM_READONLY {6584 return FExpr->getBeginLoc().getLocWithOffset(Offset);6585 }6586 6587 SourceLocation getEndLoc() const LLVM_READONLY { return FExpr->getEndLoc(); }6588};6589 6590} // namespace6591 6592static void CheckFormatString(6593 Sema &S, const FormatStringLiteral *FExpr,6594 const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr,6595 ArrayRef<const Expr *> Args, Sema::FormatArgumentPassingKind APK,6596 unsigned format_idx, unsigned firstDataArg, FormatStringType Type,6597 bool inFunctionCall, VariadicCallType CallType,6598 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,6599 bool IgnoreStringsWithoutSpecifiers);6600 6601static const Expr *maybeConstEvalStringLiteral(ASTContext &Context,6602 const Expr *E);6603 6604// Determine if an expression is a string literal or constant string.6605// If this function returns false on the arguments to a function expecting a6606// format string, we will usually need to emit a warning.6607// True string literals are then checked by CheckFormatString.6608static StringLiteralCheckType checkFormatStringExpr(6609 Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E,6610 ArrayRef<const Expr *> Args, Sema::FormatArgumentPassingKind APK,6611 unsigned format_idx, unsigned firstDataArg, FormatStringType Type,6612 VariadicCallType CallType, bool InFunctionCall,6613 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,6614 llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers = false) {6615 if (S.isConstantEvaluatedContext())6616 return SLCT_NotALiteral;6617tryAgain:6618 assert(Offset.isSigned() && "invalid offset");6619 6620 if (E->isTypeDependent() || E->isValueDependent())6621 return SLCT_NotALiteral;6622 6623 E = E->IgnoreParenCasts();6624 6625 if (E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull))6626 // Technically -Wformat-nonliteral does not warn about this case.6627 // The behavior of printf and friends in this case is implementation6628 // dependent. Ideally if the format string cannot be null then6629 // it should have a 'nonnull' attribute in the function prototype.6630 return SLCT_UncheckedLiteral;6631 6632 switch (E->getStmtClass()) {6633 case Stmt::InitListExprClass:6634 // Handle expressions like {"foobar"}.6635 if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {6636 return checkFormatStringExpr(6637 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,6638 Type, CallType, /*InFunctionCall*/ false, CheckedVarArgs,6639 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);6640 }6641 return SLCT_NotALiteral;6642 case Stmt::BinaryConditionalOperatorClass:6643 case Stmt::ConditionalOperatorClass: {6644 // The expression is a literal if both sub-expressions were, and it was6645 // completely checked only if both sub-expressions were checked.6646 const AbstractConditionalOperator *C =6647 cast<AbstractConditionalOperator>(E);6648 6649 // Determine whether it is necessary to check both sub-expressions, for6650 // example, because the condition expression is a constant that can be6651 // evaluated at compile time.6652 bool CheckLeft = true, CheckRight = true;6653 6654 bool Cond;6655 if (C->getCond()->EvaluateAsBooleanCondition(6656 Cond, S.getASTContext(), S.isConstantEvaluatedContext())) {6657 if (Cond)6658 CheckRight = false;6659 else6660 CheckLeft = false;6661 }6662 6663 // We need to maintain the offsets for the right and the left hand side6664 // separately to check if every possible indexed expression is a valid6665 // string literal. They might have different offsets for different string6666 // literals in the end.6667 StringLiteralCheckType Left;6668 if (!CheckLeft)6669 Left = SLCT_UncheckedLiteral;6670 else {6671 Left = checkFormatStringExpr(6672 S, ReferenceFormatString, C->getTrueExpr(), Args, APK, format_idx,6673 firstDataArg, Type, CallType, InFunctionCall, CheckedVarArgs,6674 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);6675 if (Left == SLCT_NotALiteral || !CheckRight) {6676 return Left;6677 }6678 }6679 6680 StringLiteralCheckType Right = checkFormatStringExpr(6681 S, ReferenceFormatString, C->getFalseExpr(), Args, APK, format_idx,6682 firstDataArg, Type, CallType, InFunctionCall, CheckedVarArgs,6683 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);6684 6685 return (CheckLeft && Left < Right) ? Left : Right;6686 }6687 6688 case Stmt::ImplicitCastExprClass:6689 E = cast<ImplicitCastExpr>(E)->getSubExpr();6690 goto tryAgain;6691 6692 case Stmt::OpaqueValueExprClass:6693 if (const Expr *src = cast<OpaqueValueExpr>(E)->getSourceExpr()) {6694 E = src;6695 goto tryAgain;6696 }6697 return SLCT_NotALiteral;6698 6699 case Stmt::PredefinedExprClass:6700 // While __func__, etc., are technically not string literals, they6701 // cannot contain format specifiers and thus are not a security6702 // liability.6703 return SLCT_UncheckedLiteral;6704 6705 case Stmt::DeclRefExprClass: {6706 const DeclRefExpr *DR = cast<DeclRefExpr>(E);6707 6708 // As an exception, do not flag errors for variables binding to6709 // const string literals.6710 if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {6711 bool isConstant = false;6712 QualType T = DR->getType();6713 6714 if (const ArrayType *AT = S.Context.getAsArrayType(T)) {6715 isConstant = AT->getElementType().isConstant(S.Context);6716 } else if (const PointerType *PT = T->getAs<PointerType>()) {6717 isConstant = T.isConstant(S.Context) &&6718 PT->getPointeeType().isConstant(S.Context);6719 } else if (T->isObjCObjectPointerType()) {6720 // In ObjC, there is usually no "const ObjectPointer" type,6721 // so don't check if the pointee type is constant.6722 isConstant = T.isConstant(S.Context);6723 }6724 6725 if (isConstant) {6726 if (const Expr *Init = VD->getAnyInitializer()) {6727 // Look through initializers like const char c[] = { "foo" }6728 if (const InitListExpr *InitList = dyn_cast<InitListExpr>(Init)) {6729 if (InitList->isStringLiteralInit())6730 Init = InitList->getInit(0)->IgnoreParenImpCasts();6731 }6732 return checkFormatStringExpr(6733 S, ReferenceFormatString, Init, Args, APK, format_idx,6734 firstDataArg, Type, CallType,6735 /*InFunctionCall*/ false, CheckedVarArgs, UncoveredArg, Offset);6736 }6737 }6738 6739 // When the format argument is an argument of this function, and this6740 // function also has the format attribute, there are several interactions6741 // for which there shouldn't be a warning. For instance, when calling6742 // v*printf from a function that has the printf format attribute, we6743 // should not emit a warning about using `fmt`, even though it's not6744 // constant, because the arguments have already been checked for the6745 // caller of `logmessage`:6746 //6747 // __attribute__((format(printf, 1, 2)))6748 // void logmessage(char const *fmt, ...) {6749 // va_list ap;6750 // va_start(ap, fmt);6751 // vprintf(fmt, ap); /* do not emit a warning about "fmt" */6752 // ...6753 // }6754 //6755 // Another interaction that we need to support is using a format string6756 // specified by the format_matches attribute:6757 //6758 // __attribute__((format_matches(printf, 1, "%s %d")))6759 // void logmessage(char const *fmt, const char *a, int b) {6760 // printf(fmt, a, b); /* do not emit a warning about "fmt" */6761 // printf(fmt, 123.4); /* emit warnings that "%s %d" is incompatible */6762 // ...6763 // }6764 //6765 // Yet another interaction that we need to support is calling a variadic6766 // format function from a format function that has fixed arguments. For6767 // instance:6768 //6769 // __attribute__((format(printf, 1, 2)))6770 // void logstring(char const *fmt, char const *str) {6771 // printf(fmt, str); /* do not emit a warning about "fmt" */6772 // }6773 //6774 // Same (and perhaps more relatably) for the variadic template case:6775 //6776 // template<typename... Args>6777 // __attribute__((format(printf, 1, 2)))6778 // void log(const char *fmt, Args&&... args) {6779 // printf(fmt, forward<Args>(args)...);6780 // /* do not emit a warning about "fmt" */6781 // }6782 //6783 // Due to implementation difficulty, we only check the format, not the6784 // format arguments, in all cases.6785 //6786 if (const auto *PV = dyn_cast<ParmVarDecl>(VD)) {6787 if (const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {6788 for (const auto *PVFormatMatches :6789 D->specific_attrs<FormatMatchesAttr>()) {6790 Sema::FormatStringInfo CalleeFSI;6791 if (!Sema::getFormatStringInfo(D, PVFormatMatches->getFormatIdx(),6792 0, &CalleeFSI))6793 continue;6794 if (PV->getFunctionScopeIndex() == CalleeFSI.FormatIdx) {6795 // If using the wrong type of format string, emit a diagnostic6796 // here and stop checking to avoid irrelevant diagnostics.6797 if (Type != S.GetFormatStringType(PVFormatMatches)) {6798 S.Diag(Args[format_idx]->getBeginLoc(),6799 diag::warn_format_string_type_incompatible)6800 << PVFormatMatches->getType()->getName()6801 << S.GetFormatStringTypeName(Type);6802 if (!InFunctionCall) {6803 S.Diag(PVFormatMatches->getFormatString()->getBeginLoc(),6804 diag::note_format_string_defined);6805 }6806 return SLCT_UncheckedLiteral;6807 }6808 return checkFormatStringExpr(6809 S, ReferenceFormatString, PVFormatMatches->getFormatString(),6810 Args, APK, format_idx, firstDataArg, Type, CallType,6811 /*InFunctionCall*/ false, CheckedVarArgs, UncoveredArg,6812 Offset, IgnoreStringsWithoutSpecifiers);6813 }6814 }6815 6816 for (const auto *PVFormat : D->specific_attrs<FormatAttr>()) {6817 Sema::FormatStringInfo CallerFSI;6818 if (!Sema::getFormatStringInfo(D, PVFormat->getFormatIdx(),6819 PVFormat->getFirstArg(), &CallerFSI))6820 continue;6821 if (PV->getFunctionScopeIndex() == CallerFSI.FormatIdx) {6822 // We also check if the formats are compatible.6823 // We can't pass a 'scanf' string to a 'printf' function.6824 if (Type != S.GetFormatStringType(PVFormat)) {6825 S.Diag(Args[format_idx]->getBeginLoc(),6826 diag::warn_format_string_type_incompatible)6827 << PVFormat->getType()->getName()6828 << S.GetFormatStringTypeName(Type);6829 if (!InFunctionCall) {6830 S.Diag(E->getBeginLoc(), diag::note_format_string_defined);6831 }6832 return SLCT_UncheckedLiteral;6833 }6834 // Lastly, check that argument passing kinds transition in a6835 // way that makes sense:6836 // from a caller with FAPK_VAList, allow FAPK_VAList6837 // from a caller with FAPK_Fixed, allow FAPK_Fixed6838 // from a caller with FAPK_Fixed, allow FAPK_Variadic6839 // from a caller with FAPK_Variadic, allow FAPK_VAList6840 switch (combineFAPK(CallerFSI.ArgPassingKind, APK)) {6841 case combineFAPK(Sema::FAPK_VAList, Sema::FAPK_VAList):6842 case combineFAPK(Sema::FAPK_Fixed, Sema::FAPK_Fixed):6843 case combineFAPK(Sema::FAPK_Fixed, Sema::FAPK_Variadic):6844 case combineFAPK(Sema::FAPK_Variadic, Sema::FAPK_VAList):6845 return SLCT_UncheckedLiteral;6846 }6847 }6848 }6849 }6850 }6851 }6852 6853 return SLCT_NotALiteral;6854 }6855 6856 case Stmt::CallExprClass:6857 case Stmt::CXXMemberCallExprClass: {6858 const CallExpr *CE = cast<CallExpr>(E);6859 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {6860 bool IsFirst = true;6861 StringLiteralCheckType CommonResult;6862 for (const auto *FA : ND->specific_attrs<FormatArgAttr>()) {6863 const Expr *Arg = CE->getArg(FA->getFormatIdx().getASTIndex());6864 StringLiteralCheckType Result = checkFormatStringExpr(6865 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,6866 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,6867 Offset, IgnoreStringsWithoutSpecifiers);6868 if (IsFirst) {6869 CommonResult = Result;6870 IsFirst = false;6871 }6872 }6873 if (!IsFirst)6874 return CommonResult;6875 6876 if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {6877 unsigned BuiltinID = FD->getBuiltinID();6878 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||6879 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {6880 const Expr *Arg = CE->getArg(0);6881 return checkFormatStringExpr(6882 S, ReferenceFormatString, Arg, Args, APK, format_idx,6883 firstDataArg, Type, CallType, InFunctionCall, CheckedVarArgs,6884 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);6885 }6886 }6887 }6888 if (const Expr *SLE = maybeConstEvalStringLiteral(S.Context, E))6889 return checkFormatStringExpr(6890 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,6891 Type, CallType, /*InFunctionCall*/ false, CheckedVarArgs,6892 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);6893 return SLCT_NotALiteral;6894 }6895 case Stmt::ObjCMessageExprClass: {6896 const auto *ME = cast<ObjCMessageExpr>(E);6897 if (const auto *MD = ME->getMethodDecl()) {6898 if (const auto *FA = MD->getAttr<FormatArgAttr>()) {6899 // As a special case heuristic, if we're using the method -[NSBundle6900 // localizedStringForKey:value:table:], ignore any key strings that lack6901 // format specifiers. The idea is that if the key doesn't have any6902 // format specifiers then its probably just a key to map to the6903 // localized strings. If it does have format specifiers though, then its6904 // likely that the text of the key is the format string in the6905 // programmer's language, and should be checked.6906 const ObjCInterfaceDecl *IFace;6907 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&6908 IFace->getIdentifier()->isStr("NSBundle") &&6909 MD->getSelector().isKeywordSelector(6910 {"localizedStringForKey", "value", "table"})) {6911 IgnoreStringsWithoutSpecifiers = true;6912 }6913 6914 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());6915 return checkFormatStringExpr(6916 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,6917 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,6918 Offset, IgnoreStringsWithoutSpecifiers);6919 }6920 }6921 6922 return SLCT_NotALiteral;6923 }6924 case Stmt::ObjCStringLiteralClass:6925 case Stmt::StringLiteralClass: {6926 const StringLiteral *StrE = nullptr;6927 6928 if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E))6929 StrE = ObjCFExpr->getString();6930 else6931 StrE = cast<StringLiteral>(E);6932 6933 if (StrE) {6934 if (Offset.isNegative() || Offset > StrE->getLength()) {6935 // TODO: It would be better to have an explicit warning for out of6936 // bounds literals.6937 return SLCT_NotALiteral;6938 }6939 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());6940 CheckFormatString(S, &FStr, ReferenceFormatString, E, Args, APK,6941 format_idx, firstDataArg, Type, InFunctionCall,6942 CallType, CheckedVarArgs, UncoveredArg,6943 IgnoreStringsWithoutSpecifiers);6944 return SLCT_CheckedLiteral;6945 }6946 6947 return SLCT_NotALiteral;6948 }6949 case Stmt::BinaryOperatorClass: {6950 const BinaryOperator *BinOp = cast<BinaryOperator>(E);6951 6952 // A string literal + an int offset is still a string literal.6953 if (BinOp->isAdditiveOp()) {6954 Expr::EvalResult LResult, RResult;6955 6956 bool LIsInt = BinOp->getLHS()->EvaluateAsInt(6957 LResult, S.Context, Expr::SE_NoSideEffects,6958 S.isConstantEvaluatedContext());6959 bool RIsInt = BinOp->getRHS()->EvaluateAsInt(6960 RResult, S.Context, Expr::SE_NoSideEffects,6961 S.isConstantEvaluatedContext());6962 6963 if (LIsInt != RIsInt) {6964 BinaryOperatorKind BinOpKind = BinOp->getOpcode();6965 6966 if (LIsInt) {6967 if (BinOpKind == BO_Add) {6968 sumOffsets(Offset, LResult.Val.getInt(), BinOpKind, RIsInt);6969 E = BinOp->getRHS();6970 goto tryAgain;6971 }6972 } else {6973 sumOffsets(Offset, RResult.Val.getInt(), BinOpKind, RIsInt);6974 E = BinOp->getLHS();6975 goto tryAgain;6976 }6977 }6978 }6979 6980 return SLCT_NotALiteral;6981 }6982 case Stmt::UnaryOperatorClass: {6983 const UnaryOperator *UnaOp = cast<UnaryOperator>(E);6984 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->getSubExpr());6985 if (UnaOp->getOpcode() == UO_AddrOf && ASE) {6986 Expr::EvalResult IndexResult;6987 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.Context,6988 Expr::SE_NoSideEffects,6989 S.isConstantEvaluatedContext())) {6990 sumOffsets(Offset, IndexResult.Val.getInt(), BO_Add,6991 /*RHS is int*/ true);6992 E = ASE->getBase();6993 goto tryAgain;6994 }6995 }6996 6997 return SLCT_NotALiteral;6998 }6999 7000 default:7001 return SLCT_NotALiteral;7002 }7003}7004 7005// If this expression can be evaluated at compile-time,7006// check if the result is a StringLiteral and return it7007// otherwise return nullptr7008static const Expr *maybeConstEvalStringLiteral(ASTContext &Context,7009 const Expr *E) {7010 Expr::EvalResult Result;7011 if (E->EvaluateAsRValue(Result, Context) && Result.Val.isLValue()) {7012 const auto *LVE = Result.Val.getLValueBase().dyn_cast<const Expr *>();7013 if (isa_and_nonnull<StringLiteral>(LVE))7014 return LVE;7015 }7016 return nullptr;7017}7018 7019StringRef Sema::GetFormatStringTypeName(FormatStringType FST) {7020 switch (FST) {7021 case FormatStringType::Scanf:7022 return "scanf";7023 case FormatStringType::Printf:7024 return "printf";7025 case FormatStringType::NSString:7026 return "NSString";7027 case FormatStringType::Strftime:7028 return "strftime";7029 case FormatStringType::Strfmon:7030 return "strfmon";7031 case FormatStringType::Kprintf:7032 return "kprintf";7033 case FormatStringType::FreeBSDKPrintf:7034 return "freebsd_kprintf";7035 case FormatStringType::OSLog:7036 return "os_log";7037 default:7038 return "<unknown>";7039 }7040}7041 7042FormatStringType Sema::GetFormatStringType(StringRef Flavor) {7043 return llvm::StringSwitch<FormatStringType>(Flavor)7044 .Cases({"gnu_scanf", "scanf"}, FormatStringType::Scanf)7045 .Cases({"gnu_printf", "printf", "printf0", "syslog"},7046 FormatStringType::Printf)7047 .Cases({"NSString", "CFString"}, FormatStringType::NSString)7048 .Cases({"gnu_strftime", "strftime"}, FormatStringType::Strftime)7049 .Cases({"gnu_strfmon", "strfmon"}, FormatStringType::Strfmon)7050 .Cases({"kprintf", "cmn_err", "vcmn_err", "zcmn_err"},7051 FormatStringType::Kprintf)7052 .Case("freebsd_kprintf", FormatStringType::FreeBSDKPrintf)7053 .Case("os_trace", FormatStringType::OSLog)7054 .Case("os_log", FormatStringType::OSLog)7055 .Default(FormatStringType::Unknown);7056}7057 7058FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) {7059 return GetFormatStringType(Format->getType()->getName());7060}7061 7062FormatStringType Sema::GetFormatStringType(const FormatMatchesAttr *Format) {7063 return GetFormatStringType(Format->getType()->getName());7064}7065 7066bool Sema::CheckFormatArguments(const FormatAttr *Format,7067 ArrayRef<const Expr *> Args, bool IsCXXMember,7068 VariadicCallType CallType, SourceLocation Loc,7069 SourceRange Range,7070 llvm::SmallBitVector &CheckedVarArgs) {7071 FormatStringInfo FSI;7072 if (getFormatStringInfo(Format->getFormatIdx(), Format->getFirstArg(),7073 IsCXXMember,7074 CallType != VariadicCallType::DoesNotApply, &FSI))7075 return CheckFormatArguments(7076 Args, FSI.ArgPassingKind, nullptr, FSI.FormatIdx, FSI.FirstDataArg,7077 GetFormatStringType(Format), CallType, Loc, Range, CheckedVarArgs);7078 return false;7079}7080 7081bool Sema::CheckFormatString(const FormatMatchesAttr *Format,7082 ArrayRef<const Expr *> Args, bool IsCXXMember,7083 VariadicCallType CallType, SourceLocation Loc,7084 SourceRange Range,7085 llvm::SmallBitVector &CheckedVarArgs) {7086 FormatStringInfo FSI;7087 if (getFormatStringInfo(Format->getFormatIdx(), 0, IsCXXMember, false,7088 &FSI)) {7089 FSI.ArgPassingKind = Sema::FAPK_Elsewhere;7090 return CheckFormatArguments(Args, FSI.ArgPassingKind,7091 Format->getFormatString(), FSI.FormatIdx,7092 FSI.FirstDataArg, GetFormatStringType(Format),7093 CallType, Loc, Range, CheckedVarArgs);7094 }7095 return false;7096}7097 7098bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args,7099 Sema::FormatArgumentPassingKind APK,7100 const StringLiteral *ReferenceFormatString,7101 unsigned format_idx, unsigned firstDataArg,7102 FormatStringType Type,7103 VariadicCallType CallType, SourceLocation Loc,7104 SourceRange Range,7105 llvm::SmallBitVector &CheckedVarArgs) {7106 // CHECK: printf/scanf-like function is called with no format string.7107 if (format_idx >= Args.size()) {7108 Diag(Loc, diag::warn_missing_format_string) << Range;7109 return false;7110 }7111 7112 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();7113 7114 // CHECK: format string is not a string literal.7115 //7116 // Dynamically generated format strings are difficult to7117 // automatically vet at compile time. Requiring that format strings7118 // are string literals: (1) permits the checking of format strings by7119 // the compiler and thereby (2) can practically remove the source of7120 // many format string exploits.7121 7122 // Format string can be either ObjC string (e.g. @"%d") or7123 // C string (e.g. "%d")7124 // ObjC string uses the same format specifiers as C string, so we can use7125 // the same format string checking logic for both ObjC and C strings.7126 UncoveredArgHandler UncoveredArg;7127 StringLiteralCheckType CT = checkFormatStringExpr(7128 *this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,7129 firstDataArg, Type, CallType,7130 /*IsFunctionCall*/ true, CheckedVarArgs, UncoveredArg,7131 /*no string offset*/ llvm::APSInt(64, false) = 0);7132 7133 // Generate a diagnostic where an uncovered argument is detected.7134 if (UncoveredArg.hasUncoveredArg()) {7135 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;7136 assert(ArgIdx < Args.size() && "ArgIdx outside bounds");7137 UncoveredArg.Diagnose(*this, /*IsFunctionCall*/true, Args[ArgIdx]);7138 }7139 7140 if (CT != SLCT_NotALiteral)7141 // Literal format string found, check done!7142 return CT == SLCT_CheckedLiteral;7143 7144 // Strftime is particular as it always uses a single 'time' argument,7145 // so it is safe to pass a non-literal string.7146 if (Type == FormatStringType::Strftime)7147 return false;7148 7149 // Do not emit diag when the string param is a macro expansion and the7150 // format is either NSString or CFString. This is a hack to prevent7151 // diag when using the NSLocalizedString and CFCopyLocalizedString macros7152 // which are usually used in place of NS and CF string literals.7153 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();7154 if (Type == FormatStringType::NSString &&7155 SourceMgr.isInSystemMacro(FormatLoc))7156 return false;7157 7158 // If there are no arguments specified, warn with -Wformat-security, otherwise7159 // warn only with -Wformat-nonliteral.7160 if (Args.size() == firstDataArg) {7161 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)7162 << OrigFormatExpr->getSourceRange();7163 switch (Type) {7164 default:7165 break;7166 case FormatStringType::Kprintf:7167 case FormatStringType::FreeBSDKPrintf:7168 case FormatStringType::Printf:7169 Diag(FormatLoc, diag::note_format_security_fixit)7170 << FixItHint::CreateInsertion(FormatLoc, "\"%s\", ");7171 break;7172 case FormatStringType::NSString:7173 Diag(FormatLoc, diag::note_format_security_fixit)7174 << FixItHint::CreateInsertion(FormatLoc, "@\"%@\", ");7175 break;7176 }7177 } else {7178 Diag(FormatLoc, diag::warn_format_nonliteral)7179 << OrigFormatExpr->getSourceRange();7180 }7181 return false;7182}7183 7184namespace {7185 7186class CheckFormatHandler : public analyze_format_string::FormatStringHandler {7187protected:7188 Sema &S;7189 const FormatStringLiteral *FExpr;7190 const Expr *OrigFormatExpr;7191 const FormatStringType FSType;7192 const unsigned FirstDataArg;7193 const unsigned NumDataArgs;7194 const char *Beg; // Start of format string.7195 const Sema::FormatArgumentPassingKind ArgPassingKind;7196 ArrayRef<const Expr *> Args;7197 unsigned FormatIdx;7198 llvm::SmallBitVector CoveredArgs;7199 bool usesPositionalArgs = false;7200 bool atFirstArg = true;7201 bool inFunctionCall;7202 VariadicCallType CallType;7203 llvm::SmallBitVector &CheckedVarArgs;7204 UncoveredArgHandler &UncoveredArg;7205 7206public:7207 CheckFormatHandler(Sema &s, const FormatStringLiteral *fexpr,7208 const Expr *origFormatExpr, const FormatStringType type,7209 unsigned firstDataArg, unsigned numDataArgs,7210 const char *beg, Sema::FormatArgumentPassingKind APK,7211 ArrayRef<const Expr *> Args, unsigned formatIdx,7212 bool inFunctionCall, VariadicCallType callType,7213 llvm::SmallBitVector &CheckedVarArgs,7214 UncoveredArgHandler &UncoveredArg)7215 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(type),7216 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),7217 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),7218 inFunctionCall(inFunctionCall), CallType(callType),7219 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {7220 CoveredArgs.resize(numDataArgs);7221 CoveredArgs.reset();7222 }7223 7224 bool HasFormatArguments() const {7225 return ArgPassingKind == Sema::FAPK_Fixed ||7226 ArgPassingKind == Sema::FAPK_Variadic;7227 }7228 7229 void DoneProcessing();7230 7231 void HandleIncompleteSpecifier(const char *startSpecifier,7232 unsigned specifierLen) override;7233 7234 void HandleInvalidLengthModifier(7235 const analyze_format_string::FormatSpecifier &FS,7236 const analyze_format_string::ConversionSpecifier &CS,7237 const char *startSpecifier, unsigned specifierLen,7238 unsigned DiagID);7239 7240 void HandleNonStandardLengthModifier(7241 const analyze_format_string::FormatSpecifier &FS,7242 const char *startSpecifier, unsigned specifierLen);7243 7244 void HandleNonStandardConversionSpecifier(7245 const analyze_format_string::ConversionSpecifier &CS,7246 const char *startSpecifier, unsigned specifierLen);7247 7248 void HandlePosition(const char *startPos, unsigned posLen) override;7249 7250 void HandleInvalidPosition(const char *startSpecifier,7251 unsigned specifierLen,7252 analyze_format_string::PositionContext p) override;7253 7254 void HandleZeroPosition(const char *startPos, unsigned posLen) override;7255 7256 void HandleNullChar(const char *nullCharacter) override;7257 7258 template <typename Range>7259 static void7260 EmitFormatDiagnostic(Sema &S, bool inFunctionCall, const Expr *ArgumentExpr,7261 const PartialDiagnostic &PDiag, SourceLocation StringLoc,7262 bool IsStringLocation, Range StringRange,7263 ArrayRef<FixItHint> Fixit = {});7264 7265protected:7266 bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc,7267 const char *startSpec,7268 unsigned specifierLen,7269 const char *csStart, unsigned csLen);7270 7271 void HandlePositionalNonpositionalArgs(SourceLocation Loc,7272 const char *startSpec,7273 unsigned specifierLen);7274 7275 SourceRange getFormatStringRange();7276 CharSourceRange getSpecifierRange(const char *startSpecifier,7277 unsigned specifierLen);7278 SourceLocation getLocationOfByte(const char *x);7279 7280 const Expr *getDataArg(unsigned i) const;7281 7282 bool CheckNumArgs(const analyze_format_string::FormatSpecifier &FS,7283 const analyze_format_string::ConversionSpecifier &CS,7284 const char *startSpecifier, unsigned specifierLen,7285 unsigned argIndex);7286 7287 template <typename Range>7288 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,7289 bool IsStringLocation, Range StringRange,7290 ArrayRef<FixItHint> Fixit = {});7291};7292 7293} // namespace7294 7295SourceRange CheckFormatHandler::getFormatStringRange() {7296 return OrigFormatExpr->getSourceRange();7297}7298 7299CharSourceRange CheckFormatHandler::7300getSpecifierRange(const char *startSpecifier, unsigned specifierLen) {7301 SourceLocation Start = getLocationOfByte(startSpecifier);7302 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);7303 7304 // Advance the end SourceLocation by one due to half-open ranges.7305 End = End.getLocWithOffset(1);7306 7307 return CharSourceRange::getCharRange(Start, End);7308}7309 7310SourceLocation CheckFormatHandler::getLocationOfByte(const char *x) {7311 return FExpr->getLocationOfByte(x - Beg, S.getSourceManager(),7312 S.getLangOpts(), S.Context.getTargetInfo());7313}7314 7315void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier,7316 unsigned specifierLen){7317 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_incomplete_specifier),7318 getLocationOfByte(startSpecifier),7319 /*IsStringLocation*/true,7320 getSpecifierRange(startSpecifier, specifierLen));7321}7322 7323void CheckFormatHandler::HandleInvalidLengthModifier(7324 const analyze_format_string::FormatSpecifier &FS,7325 const analyze_format_string::ConversionSpecifier &CS,7326 const char *startSpecifier, unsigned specifierLen, unsigned DiagID) {7327 using namespace analyze_format_string;7328 7329 const LengthModifier &LM = FS.getLengthModifier();7330 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());7331 7332 // See if we know how to fix this length modifier.7333 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();7334 if (FixedLM) {7335 EmitFormatDiagnostic(S.PDiag(DiagID) << LM.toString() << CS.toString(),7336 getLocationOfByte(LM.getStart()),7337 /*IsStringLocation*/true,7338 getSpecifierRange(startSpecifier, specifierLen));7339 7340 S.Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)7341 << FixedLM->toString()7342 << FixItHint::CreateReplacement(LMRange, FixedLM->toString());7343 7344 } else {7345 FixItHint Hint;7346 if (DiagID == diag::warn_format_nonsensical_length)7347 Hint = FixItHint::CreateRemoval(LMRange);7348 7349 EmitFormatDiagnostic(S.PDiag(DiagID) << LM.toString() << CS.toString(),7350 getLocationOfByte(LM.getStart()),7351 /*IsStringLocation*/true,7352 getSpecifierRange(startSpecifier, specifierLen),7353 Hint);7354 }7355}7356 7357void CheckFormatHandler::HandleNonStandardLengthModifier(7358 const analyze_format_string::FormatSpecifier &FS,7359 const char *startSpecifier, unsigned specifierLen) {7360 using namespace analyze_format_string;7361 7362 const LengthModifier &LM = FS.getLengthModifier();7363 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());7364 7365 // See if we know how to fix this length modifier.7366 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();7367 if (FixedLM) {7368 EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)7369 << LM.toString() << 0,7370 getLocationOfByte(LM.getStart()),7371 /*IsStringLocation*/true,7372 getSpecifierRange(startSpecifier, specifierLen));7373 7374 S.Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)7375 << FixedLM->toString()7376 << FixItHint::CreateReplacement(LMRange, FixedLM->toString());7377 7378 } else {7379 EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)7380 << LM.toString() << 0,7381 getLocationOfByte(LM.getStart()),7382 /*IsStringLocation*/true,7383 getSpecifierRange(startSpecifier, specifierLen));7384 }7385}7386 7387void CheckFormatHandler::HandleNonStandardConversionSpecifier(7388 const analyze_format_string::ConversionSpecifier &CS,7389 const char *startSpecifier, unsigned specifierLen) {7390 using namespace analyze_format_string;7391 7392 // See if we know how to fix this conversion specifier.7393 std::optional<ConversionSpecifier> FixedCS = CS.getStandardSpecifier();7394 if (FixedCS) {7395 EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)7396 << CS.toString() << /*conversion specifier*/1,7397 getLocationOfByte(CS.getStart()),7398 /*IsStringLocation*/true,7399 getSpecifierRange(startSpecifier, specifierLen));7400 7401 CharSourceRange CSRange = getSpecifierRange(CS.getStart(), CS.getLength());7402 S.Diag(getLocationOfByte(CS.getStart()), diag::note_format_fix_specifier)7403 << FixedCS->toString()7404 << FixItHint::CreateReplacement(CSRange, FixedCS->toString());7405 } else {7406 EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)7407 << CS.toString() << /*conversion specifier*/1,7408 getLocationOfByte(CS.getStart()),7409 /*IsStringLocation*/true,7410 getSpecifierRange(startSpecifier, specifierLen));7411 }7412}7413 7414void CheckFormatHandler::HandlePosition(const char *startPos,7415 unsigned posLen) {7416 if (!S.getDiagnostics().isIgnored(7417 diag::warn_format_non_standard_positional_arg, SourceLocation()))7418 EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard_positional_arg),7419 getLocationOfByte(startPos),7420 /*IsStringLocation*/ true,7421 getSpecifierRange(startPos, posLen));7422}7423 7424void CheckFormatHandler::HandleInvalidPosition(7425 const char *startSpecifier, unsigned specifierLen,7426 analyze_format_string::PositionContext p) {7427 if (!S.getDiagnostics().isIgnored(7428 diag::warn_format_invalid_positional_specifier, SourceLocation()))7429 EmitFormatDiagnostic(7430 S.PDiag(diag::warn_format_invalid_positional_specifier) << (unsigned)p,7431 getLocationOfByte(startSpecifier), /*IsStringLocation*/ true,7432 getSpecifierRange(startSpecifier, specifierLen));7433}7434 7435void CheckFormatHandler::HandleZeroPosition(const char *startPos,7436 unsigned posLen) {7437 if (!S.getDiagnostics().isIgnored(diag::warn_format_zero_positional_specifier,7438 SourceLocation()))7439 EmitFormatDiagnostic(S.PDiag(diag::warn_format_zero_positional_specifier),7440 getLocationOfByte(startPos),7441 /*IsStringLocation*/ true,7442 getSpecifierRange(startPos, posLen));7443}7444 7445void CheckFormatHandler::HandleNullChar(const char *nullCharacter) {7446 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {7447 // The presence of a null character is likely an error.7448 EmitFormatDiagnostic(7449 S.PDiag(diag::warn_printf_format_string_contains_null_char),7450 getLocationOfByte(nullCharacter), /*IsStringLocation*/true,7451 getFormatStringRange());7452 }7453}7454 7455// Note that this may return NULL if there was an error parsing or building7456// one of the argument expressions.7457const Expr *CheckFormatHandler::getDataArg(unsigned i) const {7458 return Args[FirstDataArg + i];7459}7460 7461void CheckFormatHandler::DoneProcessing() {7462 // Does the number of data arguments exceed the number of7463 // format conversions in the format string?7464 if (HasFormatArguments()) {7465 // Find any arguments that weren't covered.7466 CoveredArgs.flip();7467 signed notCoveredArg = CoveredArgs.find_first();7468 if (notCoveredArg >= 0) {7469 assert((unsigned)notCoveredArg < NumDataArgs);7470 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);7471 } else {7472 UncoveredArg.setAllCovered();7473 }7474 }7475}7476 7477void UncoveredArgHandler::Diagnose(Sema &S, bool IsFunctionCall,7478 const Expr *ArgExpr) {7479 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&7480 "Invalid state");7481 7482 if (!ArgExpr)7483 return;7484 7485 SourceLocation Loc = ArgExpr->getBeginLoc();7486 7487 if (S.getSourceManager().isInSystemMacro(Loc))7488 return;7489 7490 PartialDiagnostic PDiag = S.PDiag(diag::warn_printf_data_arg_not_used);7491 for (auto E : DiagnosticExprs)7492 PDiag << E->getSourceRange();7493 7494 CheckFormatHandler::EmitFormatDiagnostic(7495 S, IsFunctionCall, DiagnosticExprs[0],7496 PDiag, Loc, /*IsStringLocation*/false,7497 DiagnosticExprs[0]->getSourceRange());7498}7499 7500bool7501CheckFormatHandler::HandleInvalidConversionSpecifier(unsigned argIndex,7502 SourceLocation Loc,7503 const char *startSpec,7504 unsigned specifierLen,7505 const char *csStart,7506 unsigned csLen) {7507 bool keepGoing = true;7508 if (argIndex < NumDataArgs) {7509 // Consider the argument coverered, even though the specifier doesn't7510 // make sense.7511 CoveredArgs.set(argIndex);7512 }7513 else {7514 // If argIndex exceeds the number of data arguments we7515 // don't issue a warning because that is just a cascade of warnings (and7516 // they may have intended '%%' anyway). We don't want to continue processing7517 // the format string after this point, however, as we will like just get7518 // gibberish when trying to match arguments.7519 keepGoing = false;7520 }7521 7522 StringRef Specifier(csStart, csLen);7523 7524 // If the specifier in non-printable, it could be the first byte of a UTF-87525 // sequence. In that case, print the UTF-8 code point. If not, print the byte7526 // hex value.7527 std::string CodePointStr;7528 if (!llvm::sys::locale::isPrint(*csStart)) {7529 llvm::UTF32 CodePoint;7530 const llvm::UTF8 **B = reinterpret_cast<const llvm::UTF8 **>(&csStart);7531 const llvm::UTF8 *E =7532 reinterpret_cast<const llvm::UTF8 *>(csStart + csLen);7533 llvm::ConversionResult Result =7534 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);7535 7536 if (Result != llvm::conversionOK) {7537 unsigned char FirstChar = *csStart;7538 CodePoint = (llvm::UTF32)FirstChar;7539 }7540 7541 llvm::raw_string_ostream OS(CodePointStr);7542 if (CodePoint < 256)7543 OS << "\\x" << llvm::format("%02x", CodePoint);7544 else if (CodePoint <= 0xFFFF)7545 OS << "\\u" << llvm::format("%04x", CodePoint);7546 else7547 OS << "\\U" << llvm::format("%08x", CodePoint);7548 Specifier = CodePointStr;7549 }7550 7551 EmitFormatDiagnostic(7552 S.PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,7553 /*IsStringLocation*/ true, getSpecifierRange(startSpec, specifierLen));7554 7555 return keepGoing;7556}7557 7558void7559CheckFormatHandler::HandlePositionalNonpositionalArgs(SourceLocation Loc,7560 const char *startSpec,7561 unsigned specifierLen) {7562 EmitFormatDiagnostic(7563 S.PDiag(diag::warn_format_mix_positional_nonpositional_args),7564 Loc, /*isStringLoc*/true, getSpecifierRange(startSpec, specifierLen));7565}7566 7567bool7568CheckFormatHandler::CheckNumArgs(7569 const analyze_format_string::FormatSpecifier &FS,7570 const analyze_format_string::ConversionSpecifier &CS,7571 const char *startSpecifier, unsigned specifierLen, unsigned argIndex) {7572 7573 if (HasFormatArguments() && argIndex >= NumDataArgs) {7574 PartialDiagnostic PDiag = FS.usesPositionalArg()7575 ? (S.PDiag(diag::warn_printf_positional_arg_exceeds_data_args)7576 << (argIndex+1) << NumDataArgs)7577 : S.PDiag(diag::warn_printf_insufficient_data_args);7578 EmitFormatDiagnostic(7579 PDiag, getLocationOfByte(CS.getStart()), /*IsStringLocation*/true,7580 getSpecifierRange(startSpecifier, specifierLen));7581 7582 // Since more arguments than conversion tokens are given, by extension7583 // all arguments are covered, so mark this as so.7584 UncoveredArg.setAllCovered();7585 return false;7586 }7587 return true;7588}7589 7590template<typename Range>7591void CheckFormatHandler::EmitFormatDiagnostic(PartialDiagnostic PDiag,7592 SourceLocation Loc,7593 bool IsStringLocation,7594 Range StringRange,7595 ArrayRef<FixItHint> FixIt) {7596 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,7597 Loc, IsStringLocation, StringRange, FixIt);7598}7599 7600/// If the format string is not within the function call, emit a note7601/// so that the function call and string are in diagnostic messages.7602///7603/// \param InFunctionCall if true, the format string is within the function7604/// call and only one diagnostic message will be produced. Otherwise, an7605/// extra note will be emitted pointing to location of the format string.7606///7607/// \param ArgumentExpr the expression that is passed as the format string7608/// argument in the function call. Used for getting locations when two7609/// diagnostics are emitted.7610///7611/// \param PDiag the callee should already have provided any strings for the7612/// diagnostic message. This function only adds locations and fixits7613/// to diagnostics.7614///7615/// \param Loc primary location for diagnostic. If two diagnostics are7616/// required, one will be at Loc and a new SourceLocation will be created for7617/// the other one.7618///7619/// \param IsStringLocation if true, Loc points to the format string should be7620/// used for the note. Otherwise, Loc points to the argument list and will7621/// be used with PDiag.7622///7623/// \param StringRange some or all of the string to highlight. This is7624/// templated so it can accept either a CharSourceRange or a SourceRange.7625///7626/// \param FixIt optional fix it hint for the format string.7627template <typename Range>7628void CheckFormatHandler::EmitFormatDiagnostic(7629 Sema &S, bool InFunctionCall, const Expr *ArgumentExpr,7630 const PartialDiagnostic &PDiag, SourceLocation Loc, bool IsStringLocation,7631 Range StringRange, ArrayRef<FixItHint> FixIt) {7632 if (InFunctionCall) {7633 const Sema::SemaDiagnosticBuilder &D = S.Diag(Loc, PDiag);7634 D << StringRange;7635 D << FixIt;7636 } else {7637 S.Diag(IsStringLocation ? ArgumentExpr->getExprLoc() : Loc, PDiag)7638 << ArgumentExpr->getSourceRange();7639 7640 const Sema::SemaDiagnosticBuilder &Note =7641 S.Diag(IsStringLocation ? Loc : StringRange.getBegin(),7642 diag::note_format_string_defined);7643 7644 Note << StringRange;7645 Note << FixIt;7646 }7647}7648 7649//===--- CHECK: Printf format string checking -----------------------------===//7650 7651namespace {7652 7653class CheckPrintfHandler : public CheckFormatHandler {7654public:7655 CheckPrintfHandler(Sema &s, const FormatStringLiteral *fexpr,7656 const Expr *origFormatExpr, const FormatStringType type,7657 unsigned firstDataArg, unsigned numDataArgs, bool isObjC,7658 const char *beg, Sema::FormatArgumentPassingKind APK,7659 ArrayRef<const Expr *> Args, unsigned formatIdx,7660 bool inFunctionCall, VariadicCallType CallType,7661 llvm::SmallBitVector &CheckedVarArgs,7662 UncoveredArgHandler &UncoveredArg)7663 : CheckFormatHandler(s, fexpr, origFormatExpr, type, firstDataArg,7664 numDataArgs, beg, APK, Args, formatIdx,7665 inFunctionCall, CallType, CheckedVarArgs,7666 UncoveredArg) {}7667 7668 bool isObjCContext() const { return FSType == FormatStringType::NSString; }7669 7670 /// Returns true if '%@' specifiers are allowed in the format string.7671 bool allowsObjCArg() const {7672 return FSType == FormatStringType::NSString ||7673 FSType == FormatStringType::OSLog ||7674 FSType == FormatStringType::OSTrace;7675 }7676 7677 bool HandleInvalidPrintfConversionSpecifier(7678 const analyze_printf::PrintfSpecifier &FS,7679 const char *startSpecifier,7680 unsigned specifierLen) override;7681 7682 void handleInvalidMaskType(StringRef MaskType) override;7683 7684 bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,7685 const char *startSpecifier, unsigned specifierLen,7686 const TargetInfo &Target) override;7687 bool checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,7688 const char *StartSpecifier,7689 unsigned SpecifierLen,7690 const Expr *E);7691 7692 bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k,7693 const char *startSpecifier, unsigned specifierLen);7694 void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS,7695 const analyze_printf::OptionalAmount &Amt,7696 unsigned type,7697 const char *startSpecifier, unsigned specifierLen);7698 void HandleFlag(const analyze_printf::PrintfSpecifier &FS,7699 const analyze_printf::OptionalFlag &flag,7700 const char *startSpecifier, unsigned specifierLen);7701 void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS,7702 const analyze_printf::OptionalFlag &ignoredFlag,7703 const analyze_printf::OptionalFlag &flag,7704 const char *startSpecifier, unsigned specifierLen);7705 bool checkForCStrMembers(const analyze_printf::ArgType &AT,7706 const Expr *E);7707 7708 void HandleEmptyObjCModifierFlag(const char *startFlag,7709 unsigned flagLen) override;7710 7711 void HandleInvalidObjCModifierFlag(const char *startFlag,7712 unsigned flagLen) override;7713 7714 void7715 HandleObjCFlagsWithNonObjCConversion(const char *flagsStart,7716 const char *flagsEnd,7717 const char *conversionPosition) override;7718};7719 7720/// Keeps around the information needed to verify that two specifiers are7721/// compatible.7722class EquatableFormatArgument {7723public:7724 enum SpecifierSensitivity : unsigned {7725 SS_None,7726 SS_Private,7727 SS_Public,7728 SS_Sensitive7729 };7730 7731 enum FormatArgumentRole : unsigned {7732 FAR_Data,7733 FAR_FieldWidth,7734 FAR_Precision,7735 FAR_Auxiliary, // FreeBSD kernel %b and %D7736 };7737 7738private:7739 analyze_format_string::ArgType ArgType;7740 analyze_format_string::LengthModifier::Kind LengthMod;7741 StringRef SpecifierLetter;7742 CharSourceRange Range;7743 SourceLocation ElementLoc;7744 FormatArgumentRole Role : 2;7745 SpecifierSensitivity Sensitivity : 2; // only set for FAR_Data7746 unsigned Position : 14;7747 unsigned ModifierFor : 14; // not set for FAR_Data7748 7749 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag, const Expr *FmtExpr,7750 bool InFunctionCall) const;7751 7752public:7753 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,7754 analyze_format_string::LengthModifier::Kind LengthMod,7755 StringRef SpecifierLetter,7756 analyze_format_string::ArgType ArgType,7757 FormatArgumentRole Role,7758 SpecifierSensitivity Sensitivity, unsigned Position,7759 unsigned ModifierFor)7760 : ArgType(ArgType), LengthMod(LengthMod),7761 SpecifierLetter(SpecifierLetter), Range(Range), ElementLoc(ElementLoc),7762 Role(Role), Sensitivity(Sensitivity), Position(Position),7763 ModifierFor(ModifierFor) {}7764 7765 unsigned getPosition() const { return Position; }7766 SourceLocation getSourceLocation() const { return ElementLoc; }7767 CharSourceRange getSourceRange() const { return Range; }7768 analyze_format_string::LengthModifier getLengthModifier() const {7769 return analyze_format_string::LengthModifier(nullptr, LengthMod);7770 }7771 void setModifierFor(unsigned V) { ModifierFor = V; }7772 7773 std::string buildFormatSpecifier() const {7774 std::string result;7775 llvm::raw_string_ostream(result)7776 << getLengthModifier().toString() << SpecifierLetter;7777 return result;7778 }7779 7780 bool VerifyCompatible(Sema &S, const EquatableFormatArgument &Other,7781 const Expr *FmtExpr, bool InFunctionCall) const;7782};7783 7784/// Turns format strings into lists of EquatableSpecifier objects.7785class DecomposePrintfHandler : public CheckPrintfHandler {7786 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;7787 bool HadError;7788 7789 DecomposePrintfHandler(Sema &s, const FormatStringLiteral *fexpr,7790 const Expr *origFormatExpr,7791 const FormatStringType type, unsigned firstDataArg,7792 unsigned numDataArgs, bool isObjC, const char *beg,7793 Sema::FormatArgumentPassingKind APK,7794 ArrayRef<const Expr *> Args, unsigned formatIdx,7795 bool inFunctionCall, VariadicCallType CallType,7796 llvm::SmallBitVector &CheckedVarArgs,7797 UncoveredArgHandler &UncoveredArg,7798 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)7799 : CheckPrintfHandler(s, fexpr, origFormatExpr, type, firstDataArg,7800 numDataArgs, isObjC, beg, APK, Args, formatIdx,7801 inFunctionCall, CallType, CheckedVarArgs,7802 UncoveredArg),7803 Specs(Specs), HadError(false) {}7804 7805public:7806 static bool7807 GetSpecifiers(Sema &S, const FormatStringLiteral *FSL, const Expr *FmtExpr,7808 FormatStringType type, bool IsObjC, bool InFunctionCall,7809 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);7810 7811 virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,7812 const char *startSpecifier,7813 unsigned specifierLen,7814 const TargetInfo &Target) override;7815};7816 7817} // namespace7818 7819bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(7820 const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier,7821 unsigned specifierLen) {7822 const analyze_printf::PrintfConversionSpecifier &CS =7823 FS.getConversionSpecifier();7824 7825 return HandleInvalidConversionSpecifier(FS.getArgIndex(),7826 getLocationOfByte(CS.getStart()),7827 startSpecifier, specifierLen,7828 CS.getStart(), CS.getLength());7829}7830 7831void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {7832 S.Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);7833}7834 7835// Error out if struct or complex type argments are passed to os_log.7836static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType,7837 QualType T) {7838 if (FSType != FormatStringType::OSLog)7839 return false;7840 return T->isRecordType() || T->isComplexType();7841}7842 7843bool CheckPrintfHandler::HandleAmount(7844 const analyze_format_string::OptionalAmount &Amt, unsigned k,7845 const char *startSpecifier, unsigned specifierLen) {7846 if (Amt.hasDataArgument()) {7847 if (HasFormatArguments()) {7848 unsigned argIndex = Amt.getArgIndex();7849 if (argIndex >= NumDataArgs) {7850 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_asterisk_missing_arg)7851 << k,7852 getLocationOfByte(Amt.getStart()),7853 /*IsStringLocation*/ true,7854 getSpecifierRange(startSpecifier, specifierLen));7855 // Don't do any more checking. We will just emit7856 // spurious errors.7857 return false;7858 }7859 7860 // Type check the data argument. It should be an 'int'.7861 // Although not in conformance with C99, we also allow the argument to be7862 // an 'unsigned int' as that is a reasonably safe case. GCC also7863 // doesn't emit a warning for that case.7864 CoveredArgs.set(argIndex);7865 const Expr *Arg = getDataArg(argIndex);7866 if (!Arg)7867 return false;7868 7869 QualType T = Arg->getType();7870 7871 const analyze_printf::ArgType &AT = Amt.getArgType(S.Context);7872 assert(AT.isValid());7873 7874 if (!AT.matchesType(S.Context, T)) {7875 unsigned DiagID = isInvalidOSLogArgTypeForCodeGen(FSType, T)7876 ? diag::err_printf_asterisk_wrong_type7877 : diag::warn_printf_asterisk_wrong_type;7878 EmitFormatDiagnostic(S.PDiag(DiagID)7879 << k << AT.getRepresentativeTypeName(S.Context)7880 << T << Arg->getSourceRange(),7881 getLocationOfByte(Amt.getStart()),7882 /*IsStringLocation*/ true,7883 getSpecifierRange(startSpecifier, specifierLen));7884 // Don't do any more checking. We will just emit7885 // spurious errors.7886 return false;7887 }7888 }7889 }7890 return true;7891}7892 7893void CheckPrintfHandler::HandleInvalidAmount(7894 const analyze_printf::PrintfSpecifier &FS,7895 const analyze_printf::OptionalAmount &Amt,7896 unsigned type,7897 const char *startSpecifier,7898 unsigned specifierLen) {7899 const analyze_printf::PrintfConversionSpecifier &CS =7900 FS.getConversionSpecifier();7901 7902 FixItHint fixit =7903 Amt.getHowSpecified() == analyze_printf::OptionalAmount::Constant7904 ? FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(),7905 Amt.getConstantLength()))7906 : FixItHint();7907 7908 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_nonsensical_optional_amount)7909 << type << CS.toString(),7910 getLocationOfByte(Amt.getStart()),7911 /*IsStringLocation*/true,7912 getSpecifierRange(startSpecifier, specifierLen),7913 fixit);7914}7915 7916void CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS,7917 const analyze_printf::OptionalFlag &flag,7918 const char *startSpecifier,7919 unsigned specifierLen) {7920 // Warn about pointless flag with a fixit removal.7921 const analyze_printf::PrintfConversionSpecifier &CS =7922 FS.getConversionSpecifier();7923 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_nonsensical_flag)7924 << flag.toString() << CS.toString(),7925 getLocationOfByte(flag.getPosition()),7926 /*IsStringLocation*/true,7927 getSpecifierRange(startSpecifier, specifierLen),7928 FixItHint::CreateRemoval(7929 getSpecifierRange(flag.getPosition(), 1)));7930}7931 7932void CheckPrintfHandler::HandleIgnoredFlag(7933 const analyze_printf::PrintfSpecifier &FS,7934 const analyze_printf::OptionalFlag &ignoredFlag,7935 const analyze_printf::OptionalFlag &flag,7936 const char *startSpecifier,7937 unsigned specifierLen) {7938 // Warn about ignored flag with a fixit removal.7939 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_ignored_flag)7940 << ignoredFlag.toString() << flag.toString(),7941 getLocationOfByte(ignoredFlag.getPosition()),7942 /*IsStringLocation*/true,7943 getSpecifierRange(startSpecifier, specifierLen),7944 FixItHint::CreateRemoval(7945 getSpecifierRange(ignoredFlag.getPosition(), 1)));7946}7947 7948void CheckPrintfHandler::HandleEmptyObjCModifierFlag(const char *startFlag,7949 unsigned flagLen) {7950 // Warn about an empty flag.7951 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_empty_objc_flag),7952 getLocationOfByte(startFlag),7953 /*IsStringLocation*/true,7954 getSpecifierRange(startFlag, flagLen));7955}7956 7957void CheckPrintfHandler::HandleInvalidObjCModifierFlag(const char *startFlag,7958 unsigned flagLen) {7959 // Warn about an invalid flag.7960 auto Range = getSpecifierRange(startFlag, flagLen);7961 StringRef flag(startFlag, flagLen);7962 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_invalid_objc_flag) << flag,7963 getLocationOfByte(startFlag),7964 /*IsStringLocation*/true,7965 Range, FixItHint::CreateRemoval(Range));7966}7967 7968void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(7969 const char *flagsStart, const char *flagsEnd, const char *conversionPosition) {7970 // Warn about using '[...]' without a '@' conversion.7971 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);7972 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;7973 EmitFormatDiagnostic(S.PDiag(diag) << StringRef(conversionPosition, 1),7974 getLocationOfByte(conversionPosition),7975 /*IsStringLocation*/ true, Range,7976 FixItHint::CreateRemoval(Range));7977}7978 7979void EquatableFormatArgument::EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,7980 const Expr *FmtExpr,7981 bool InFunctionCall) const {7982 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,7983 ElementLoc, true, Range);7984}7985 7986bool EquatableFormatArgument::VerifyCompatible(7987 Sema &S, const EquatableFormatArgument &Other, const Expr *FmtExpr,7988 bool InFunctionCall) const {7989 using MK = analyze_format_string::ArgType::MatchKind;7990 if (Role != Other.Role) {7991 // diagnose and stop7992 EmitDiagnostic(7993 S, S.PDiag(diag::warn_format_cmp_role_mismatch) << Role << Other.Role,7994 FmtExpr, InFunctionCall);7995 S.Diag(Other.ElementLoc, diag::note_format_cmp_with) << 0 << Other.Range;7996 return false;7997 }7998 7999 if (Role != FAR_Data) {8000 if (ModifierFor != Other.ModifierFor) {8001 // diagnose and stop8002 EmitDiagnostic(S,8003 S.PDiag(diag::warn_format_cmp_modifierfor_mismatch)8004 << (ModifierFor + 1) << (Other.ModifierFor + 1),8005 FmtExpr, InFunctionCall);8006 S.Diag(Other.ElementLoc, diag::note_format_cmp_with) << 0 << Other.Range;8007 return false;8008 }8009 return true;8010 }8011 8012 bool HadError = false;8013 if (Sensitivity != Other.Sensitivity) {8014 // diagnose and continue8015 EmitDiagnostic(S,8016 S.PDiag(diag::warn_format_cmp_sensitivity_mismatch)8017 << Sensitivity << Other.Sensitivity,8018 FmtExpr, InFunctionCall);8019 HadError = S.Diag(Other.ElementLoc, diag::note_format_cmp_with)8020 << 0 << Other.Range;8021 }8022 8023 switch (ArgType.matchesArgType(S.Context, Other.ArgType)) {8024 case MK::Match:8025 break;8026 8027 case MK::MatchPromotion:8028 // Per consensus reached at https://discourse.llvm.org/t/-/83076/12,8029 // MatchPromotion is treated as a failure by format_matches.8030 case MK::NoMatch:8031 case MK::NoMatchTypeConfusion:8032 case MK::NoMatchPromotionTypeConfusion:8033 EmitDiagnostic(S,8034 S.PDiag(diag::warn_format_cmp_specifier_mismatch)8035 << buildFormatSpecifier()8036 << Other.buildFormatSpecifier(),8037 FmtExpr, InFunctionCall);8038 HadError = S.Diag(Other.ElementLoc, diag::note_format_cmp_with)8039 << 0 << Other.Range;8040 break;8041 8042 case MK::NoMatchPedantic:8043 EmitDiagnostic(S,8044 S.PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)8045 << buildFormatSpecifier()8046 << Other.buildFormatSpecifier(),8047 FmtExpr, InFunctionCall);8048 HadError = S.Diag(Other.ElementLoc, diag::note_format_cmp_with)8049 << 0 << Other.Range;8050 break;8051 8052 case MK::NoMatchSignedness:8053 EmitDiagnostic(S,8054 S.PDiag(diag::warn_format_cmp_specifier_sign_mismatch)8055 << buildFormatSpecifier()8056 << Other.buildFormatSpecifier(),8057 FmtExpr, InFunctionCall);8058 HadError = S.Diag(Other.ElementLoc, diag::note_format_cmp_with)8059 << 0 << Other.Range;8060 break;8061 }8062 return !HadError;8063}8064 8065bool DecomposePrintfHandler::GetSpecifiers(8066 Sema &S, const FormatStringLiteral *FSL, const Expr *FmtExpr,8067 FormatStringType Type, bool IsObjC, bool InFunctionCall,8068 llvm::SmallVectorImpl<EquatableFormatArgument> &Args) {8069 StringRef Data = FSL->getString();8070 const char *Str = Data.data();8071 llvm::SmallBitVector BV;8072 UncoveredArgHandler UA;8073 const Expr *PrintfArgs[] = {FSL->getFormatString()};8074 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(), Type, 0, 0, IsObjC,8075 Str, Sema::FAPK_Elsewhere, PrintfArgs, 0,8076 InFunctionCall, VariadicCallType::DoesNotApply, BV,8077 UA, Args);8078 8079 if (!analyze_format_string::ParsePrintfString(8080 H, Str, Str + Data.size(), S.getLangOpts(), S.Context.getTargetInfo(),8081 Type == FormatStringType::FreeBSDKPrintf))8082 H.DoneProcessing();8083 if (H.HadError)8084 return false;8085 8086 llvm::stable_sort(Args, [](const EquatableFormatArgument &A,8087 const EquatableFormatArgument &B) {8088 return A.getPosition() < B.getPosition();8089 });8090 return true;8091}8092 8093bool DecomposePrintfHandler::HandlePrintfSpecifier(8094 const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier,8095 unsigned specifierLen, const TargetInfo &Target) {8096 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,8097 specifierLen, Target)) {8098 HadError = true;8099 return false;8100 }8101 8102 // Do not add any specifiers to the list for %%. This is possibly incorrect8103 // if using a precision/width with a data argument, but that combination is8104 // meaningless and we wouldn't know which format to attach the8105 // precision/width to.8106 const auto &CS = FS.getConversionSpecifier();8107 if (CS.getKind() == analyze_format_string::ConversionSpecifier::PercentArg)8108 return true;8109 8110 // have to patch these to have the right ModifierFor if they are used8111 const unsigned Unset = ~0;8112 unsigned FieldWidthIndex = Unset;8113 unsigned PrecisionIndex = Unset;8114 8115 // field width?8116 const auto &FieldWidth = FS.getFieldWidth();8117 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {8118 FieldWidthIndex = Specs.size();8119 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),8120 getLocationOfByte(FieldWidth.getStart()),8121 analyze_format_string::LengthModifier::None, "*",8122 FieldWidth.getArgType(S.Context),8123 EquatableFormatArgument::FAR_FieldWidth,8124 EquatableFormatArgument::SS_None,8125 FieldWidth.usesPositionalArg()8126 ? FieldWidth.getPositionalArgIndex() - 18127 : FieldWidthIndex,8128 0);8129 }8130 // precision?8131 const auto &Precision = FS.getPrecision();8132 if (!Precision.isInvalid() && Precision.hasDataArgument()) {8133 PrecisionIndex = Specs.size();8134 Specs.emplace_back(8135 getSpecifierRange(startSpecifier, specifierLen),8136 getLocationOfByte(Precision.getStart()),8137 analyze_format_string::LengthModifier::None, ".*",8138 Precision.getArgType(S.Context), EquatableFormatArgument::FAR_Precision,8139 EquatableFormatArgument::SS_None,8140 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 18141 : PrecisionIndex,8142 0);8143 }8144 8145 // this specifier8146 unsigned SpecIndex =8147 FS.usesPositionalArg() ? FS.getPositionalArgIndex() - 1 : Specs.size();8148 if (FieldWidthIndex != Unset)8149 Specs[FieldWidthIndex].setModifierFor(SpecIndex);8150 if (PrecisionIndex != Unset)8151 Specs[PrecisionIndex].setModifierFor(SpecIndex);8152 8153 EquatableFormatArgument::SpecifierSensitivity Sensitivity;8154 if (FS.isPrivate())8155 Sensitivity = EquatableFormatArgument::SS_Private;8156 else if (FS.isPublic())8157 Sensitivity = EquatableFormatArgument::SS_Public;8158 else if (FS.isSensitive())8159 Sensitivity = EquatableFormatArgument::SS_Sensitive;8160 else8161 Sensitivity = EquatableFormatArgument::SS_None;8162 8163 Specs.emplace_back(8164 getSpecifierRange(startSpecifier, specifierLen),8165 getLocationOfByte(CS.getStart()), FS.getLengthModifier().getKind(),8166 CS.getCharacters(), FS.getArgType(S.Context, isObjCContext()),8167 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);8168 8169 // auxiliary argument?8170 if (CS.getKind() == analyze_format_string::ConversionSpecifier::FreeBSDbArg ||8171 CS.getKind() == analyze_format_string::ConversionSpecifier::FreeBSDDArg) {8172 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),8173 getLocationOfByte(CS.getStart()),8174 analyze_format_string::LengthModifier::None,8175 CS.getCharacters(),8176 analyze_format_string::ArgType::CStrTy,8177 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,8178 SpecIndex + 1, SpecIndex);8179 }8180 return true;8181}8182 8183// Determines if the specified is a C++ class or struct containing8184// a member with the specified name and kind (e.g. a CXXMethodDecl named8185// "c_str()").8186template<typename MemberKind>8187static llvm::SmallPtrSet<MemberKind*, 1>8188CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) {8189 auto *RD = Ty->getAsCXXRecordDecl();8190 llvm::SmallPtrSet<MemberKind*, 1> Results;8191 8192 if (!RD || !(RD->isBeingDefined() || RD->isCompleteDefinition()))8193 return Results;8194 8195 LookupResult R(S, &S.Context.Idents.get(Name), SourceLocation(),8196 Sema::LookupMemberName);8197 R.suppressDiagnostics();8198 8199 // We just need to include all members of the right kind turned up by the8200 // filter, at this point.8201 if (S.LookupQualifiedName(R, RD))8202 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {8203 NamedDecl *decl = (*I)->getUnderlyingDecl();8204 if (MemberKind *FK = dyn_cast<MemberKind>(decl))8205 Results.insert(FK);8206 }8207 return Results;8208}8209 8210/// Check if we could call '.c_str()' on an object.8211///8212/// FIXME: This returns the wrong results in some cases (if cv-qualifiers don't8213/// allow the call, or if it would be ambiguous).8214bool Sema::hasCStrMethod(const Expr *E) {8215 using MethodSet = llvm::SmallPtrSet<CXXMethodDecl *, 1>;8216 8217 MethodSet Results =8218 CXXRecordMembersNamed<CXXMethodDecl>("c_str", *this, E->getType());8219 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();8220 MI != ME; ++MI)8221 if ((*MI)->getMinRequiredArguments() == 0)8222 return true;8223 return false;8224}8225 8226// Check if a (w)string was passed when a (w)char* was needed, and offer a8227// better diagnostic if so. AT is assumed to be valid.8228// Returns true when a c_str() conversion method is found.8229bool CheckPrintfHandler::checkForCStrMembers(8230 const analyze_printf::ArgType &AT, const Expr *E) {8231 using MethodSet = llvm::SmallPtrSet<CXXMethodDecl *, 1>;8232 8233 MethodSet Results =8234 CXXRecordMembersNamed<CXXMethodDecl>("c_str", S, E->getType());8235 8236 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();8237 MI != ME; ++MI) {8238 const CXXMethodDecl *Method = *MI;8239 if (Method->getMinRequiredArguments() == 0 &&8240 AT.matchesType(S.Context, Method->getReturnType())) {8241 // FIXME: Suggest parens if the expression needs them.8242 SourceLocation EndLoc = S.getLocForEndOfToken(E->getEndLoc());8243 S.Diag(E->getBeginLoc(), diag::note_printf_c_str)8244 << "c_str()" << FixItHint::CreateInsertion(EndLoc, ".c_str()");8245 return true;8246 }8247 }8248 8249 return false;8250}8251 8252bool CheckPrintfHandler::HandlePrintfSpecifier(8253 const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier,8254 unsigned specifierLen, const TargetInfo &Target) {8255 using namespace analyze_format_string;8256 using namespace analyze_printf;8257 8258 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();8259 8260 if (FS.consumesDataArgument()) {8261 if (atFirstArg) {8262 atFirstArg = false;8263 usesPositionalArgs = FS.usesPositionalArg();8264 }8265 else if (usesPositionalArgs != FS.usesPositionalArg()) {8266 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),8267 startSpecifier, specifierLen);8268 return false;8269 }8270 }8271 8272 // First check if the field width, precision, and conversion specifier8273 // have matching data arguments.8274 if (!HandleAmount(FS.getFieldWidth(), /* field width */ 0,8275 startSpecifier, specifierLen)) {8276 return false;8277 }8278 8279 if (!HandleAmount(FS.getPrecision(), /* precision */ 1,8280 startSpecifier, specifierLen)) {8281 return false;8282 }8283 8284 if (!CS.consumesDataArgument()) {8285 // FIXME: Technically specifying a precision or field width here8286 // makes no sense. Worth issuing a warning at some point.8287 return true;8288 }8289 8290 // Consume the argument.8291 unsigned argIndex = FS.getArgIndex();8292 if (argIndex < NumDataArgs) {8293 // The check to see if the argIndex is valid will come later.8294 // We set the bit here because we may exit early from this8295 // function if we encounter some other error.8296 CoveredArgs.set(argIndex);8297 }8298 8299 // FreeBSD kernel extensions.8300 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||8301 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {8302 // We need at least two arguments.8303 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))8304 return false;8305 8306 if (HasFormatArguments()) {8307 // Claim the second argument.8308 CoveredArgs.set(argIndex + 1);8309 8310 // Type check the first argument (int for %b, pointer for %D)8311 const Expr *Ex = getDataArg(argIndex);8312 const analyze_printf::ArgType &AT =8313 (CS.getKind() == ConversionSpecifier::FreeBSDbArg)8314 ? ArgType(S.Context.IntTy)8315 : ArgType::CPointerTy;8316 if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType()))8317 EmitFormatDiagnostic(8318 S.PDiag(diag::warn_format_conversion_argument_type_mismatch)8319 << AT.getRepresentativeTypeName(S.Context) << Ex->getType()8320 << false << Ex->getSourceRange(),8321 Ex->getBeginLoc(), /*IsStringLocation*/ false,8322 getSpecifierRange(startSpecifier, specifierLen));8323 8324 // Type check the second argument (char * for both %b and %D)8325 Ex = getDataArg(argIndex + 1);8326 const analyze_printf::ArgType &AT2 = ArgType::CStrTy;8327 if (AT2.isValid() && !AT2.matchesType(S.Context, Ex->getType()))8328 EmitFormatDiagnostic(8329 S.PDiag(diag::warn_format_conversion_argument_type_mismatch)8330 << AT2.getRepresentativeTypeName(S.Context) << Ex->getType()8331 << false << Ex->getSourceRange(),8332 Ex->getBeginLoc(), /*IsStringLocation*/ false,8333 getSpecifierRange(startSpecifier, specifierLen));8334 }8335 return true;8336 }8337 8338 // Check for using an Objective-C specific conversion specifier8339 // in a non-ObjC literal.8340 if (!allowsObjCArg() && CS.isObjCArg()) {8341 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,8342 specifierLen);8343 }8344 8345 // %P can only be used with os_log.8346 if (FSType != FormatStringType::OSLog &&8347 CS.getKind() == ConversionSpecifier::PArg) {8348 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,8349 specifierLen);8350 }8351 8352 // %n is not allowed with os_log.8353 if (FSType == FormatStringType::OSLog &&8354 CS.getKind() == ConversionSpecifier::nArg) {8355 EmitFormatDiagnostic(S.PDiag(diag::warn_os_log_format_narg),8356 getLocationOfByte(CS.getStart()),8357 /*IsStringLocation*/ false,8358 getSpecifierRange(startSpecifier, specifierLen));8359 8360 return true;8361 }8362 8363 // Only scalars are allowed for os_trace.8364 if (FSType == FormatStringType::OSTrace &&8365 (CS.getKind() == ConversionSpecifier::PArg ||8366 CS.getKind() == ConversionSpecifier::sArg ||8367 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {8368 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,8369 specifierLen);8370 }8371 8372 // Check for use of public/private annotation outside of os_log().8373 if (FSType != FormatStringType::OSLog) {8374 if (FS.isPublic().isSet()) {8375 EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_annotation)8376 << "public",8377 getLocationOfByte(FS.isPublic().getPosition()),8378 /*IsStringLocation*/ false,8379 getSpecifierRange(startSpecifier, specifierLen));8380 }8381 if (FS.isPrivate().isSet()) {8382 EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_annotation)8383 << "private",8384 getLocationOfByte(FS.isPrivate().getPosition()),8385 /*IsStringLocation*/ false,8386 getSpecifierRange(startSpecifier, specifierLen));8387 }8388 }8389 8390 const llvm::Triple &Triple = Target.getTriple();8391 if (CS.getKind() == ConversionSpecifier::nArg &&8392 (Triple.isAndroid() || Triple.isOSFuchsia())) {8393 EmitFormatDiagnostic(S.PDiag(diag::warn_printf_narg_not_supported),8394 getLocationOfByte(CS.getStart()),8395 /*IsStringLocation*/ false,8396 getSpecifierRange(startSpecifier, specifierLen));8397 }8398 8399 // Check for invalid use of field width8400 if (!FS.hasValidFieldWidth()) {8401 HandleInvalidAmount(FS, FS.getFieldWidth(), /* field width */ 0,8402 startSpecifier, specifierLen);8403 }8404 8405 // Check for invalid use of precision8406 if (!FS.hasValidPrecision()) {8407 HandleInvalidAmount(FS, FS.getPrecision(), /* precision */ 1,8408 startSpecifier, specifierLen);8409 }8410 8411 // Precision is mandatory for %P specifier.8412 if (CS.getKind() == ConversionSpecifier::PArg &&8413 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {8414 EmitFormatDiagnostic(S.PDiag(diag::warn_format_P_no_precision),8415 getLocationOfByte(startSpecifier),8416 /*IsStringLocation*/ false,8417 getSpecifierRange(startSpecifier, specifierLen));8418 }8419 8420 // Check each flag does not conflict with any other component.8421 if (!FS.hasValidThousandsGroupingPrefix())8422 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);8423 if (!FS.hasValidLeadingZeros())8424 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);8425 if (!FS.hasValidPlusPrefix())8426 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);8427 if (!FS.hasValidSpacePrefix())8428 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);8429 if (!FS.hasValidAlternativeForm())8430 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);8431 if (!FS.hasValidLeftJustified())8432 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);8433 8434 // Check that flags are not ignored by another flag8435 if (FS.hasSpacePrefix() && FS.hasPlusPrefix()) // ' ' ignored by '+'8436 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),8437 startSpecifier, specifierLen);8438 if (FS.hasLeadingZeros() && FS.isLeftJustified()) // '0' ignored by '-'8439 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),8440 startSpecifier, specifierLen);8441 8442 // Check the length modifier is valid with the given conversion specifier.8443 if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),8444 S.getLangOpts()))8445 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,8446 diag::warn_format_nonsensical_length);8447 else if (!FS.hasStandardLengthModifier())8448 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);8449 else if (!FS.hasStandardLengthConversionCombination())8450 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,8451 diag::warn_format_non_standard_conversion_spec);8452 8453 if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))8454 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);8455 8456 // The remaining checks depend on the data arguments.8457 if (!HasFormatArguments())8458 return true;8459 8460 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))8461 return false;8462 8463 const Expr *Arg = getDataArg(argIndex);8464 if (!Arg)8465 return true;8466 8467 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);8468}8469 8470static bool requiresParensToAddCast(const Expr *E) {8471 // FIXME: We should have a general way to reason about operator8472 // precedence and whether parens are actually needed here.8473 // Take care of a few common cases where they aren't.8474 const Expr *Inside = E->IgnoreImpCasts();8475 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(Inside))8476 Inside = POE->getSyntacticForm()->IgnoreImpCasts();8477 8478 switch (Inside->getStmtClass()) {8479 case Stmt::ArraySubscriptExprClass:8480 case Stmt::CallExprClass:8481 case Stmt::CharacterLiteralClass:8482 case Stmt::CXXBoolLiteralExprClass:8483 case Stmt::DeclRefExprClass:8484 case Stmt::FloatingLiteralClass:8485 case Stmt::IntegerLiteralClass:8486 case Stmt::MemberExprClass:8487 case Stmt::ObjCArrayLiteralClass:8488 case Stmt::ObjCBoolLiteralExprClass:8489 case Stmt::ObjCBoxedExprClass:8490 case Stmt::ObjCDictionaryLiteralClass:8491 case Stmt::ObjCEncodeExprClass:8492 case Stmt::ObjCIvarRefExprClass:8493 case Stmt::ObjCMessageExprClass:8494 case Stmt::ObjCPropertyRefExprClass:8495 case Stmt::ObjCStringLiteralClass:8496 case Stmt::ObjCSubscriptRefExprClass:8497 case Stmt::ParenExprClass:8498 case Stmt::StringLiteralClass:8499 case Stmt::UnaryOperatorClass:8500 return false;8501 default:8502 return true;8503 }8504}8505 8506static std::pair<QualType, StringRef>8507shouldNotPrintDirectly(const ASTContext &Context,8508 QualType IntendedTy,8509 const Expr *E) {8510 // Use a 'while' to peel off layers of typedefs.8511 QualType TyTy = IntendedTy;8512 while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) {8513 StringRef Name = UserTy->getDecl()->getName();8514 QualType CastTy = llvm::StringSwitch<QualType>(Name)8515 .Case("CFIndex", Context.getNSIntegerType())8516 .Case("NSInteger", Context.getNSIntegerType())8517 .Case("NSUInteger", Context.getNSUIntegerType())8518 .Case("SInt32", Context.IntTy)8519 .Case("UInt32", Context.UnsignedIntTy)8520 .Default(QualType());8521 8522 if (!CastTy.isNull())8523 return std::make_pair(CastTy, Name);8524 8525 TyTy = UserTy->desugar();8526 }8527 8528 // Strip parens if necessary.8529 if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))8530 return shouldNotPrintDirectly(Context,8531 PE->getSubExpr()->getType(),8532 PE->getSubExpr());8533 8534 // If this is a conditional expression, then its result type is constructed8535 // via usual arithmetic conversions and thus there might be no necessary8536 // typedef sugar there. Recurse to operands to check for NSInteger &8537 // Co. usage condition.8538 if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {8539 QualType TrueTy, FalseTy;8540 StringRef TrueName, FalseName;8541 8542 std::tie(TrueTy, TrueName) =8543 shouldNotPrintDirectly(Context,8544 CO->getTrueExpr()->getType(),8545 CO->getTrueExpr());8546 std::tie(FalseTy, FalseName) =8547 shouldNotPrintDirectly(Context,8548 CO->getFalseExpr()->getType(),8549 CO->getFalseExpr());8550 8551 if (TrueTy == FalseTy)8552 return std::make_pair(TrueTy, TrueName);8553 else if (TrueTy.isNull())8554 return std::make_pair(FalseTy, FalseName);8555 else if (FalseTy.isNull())8556 return std::make_pair(TrueTy, TrueName);8557 }8558 8559 return std::make_pair(QualType(), StringRef());8560}8561 8562/// Return true if \p ICE is an implicit argument promotion of an arithmetic8563/// type. Bit-field 'promotions' from a higher ranked type to a lower ranked8564/// type do not count.8565static bool8566isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) {8567 QualType From = ICE->getSubExpr()->getType();8568 QualType To = ICE->getType();8569 // It's an integer promotion if the destination type is the promoted8570 // source type.8571 if (ICE->getCastKind() == CK_IntegralCast &&8572 S.Context.isPromotableIntegerType(From) &&8573 S.Context.getPromotedIntegerType(From) == To)8574 return true;8575 // Look through vector types, since we do default argument promotion for8576 // those in OpenCL.8577 if (const auto *VecTy = From->getAs<ExtVectorType>())8578 From = VecTy->getElementType();8579 if (const auto *VecTy = To->getAs<ExtVectorType>())8580 To = VecTy->getElementType();8581 // It's a floating promotion if the source type is a lower rank.8582 return ICE->getCastKind() == CK_FloatingCast &&8583 S.Context.getFloatingTypeOrder(From, To) < 0;8584}8585 8586static analyze_format_string::ArgType::MatchKind8587handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match,8588 DiagnosticsEngine &Diags, SourceLocation Loc) {8589 if (Match == analyze_format_string::ArgType::NoMatchSignedness) {8590 if (Diags.isIgnored(8591 diag::warn_format_conversion_argument_type_mismatch_signedness,8592 Loc) ||8593 Diags.isIgnored(8594 // Arbitrary -Wformat diagnostic to detect -Wno-format:8595 diag::warn_format_conversion_argument_type_mismatch, Loc)) {8596 return analyze_format_string::ArgType::Match;8597 }8598 }8599 return Match;8600}8601 8602bool8603CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,8604 const char *StartSpecifier,8605 unsigned SpecifierLen,8606 const Expr *E) {8607 using namespace analyze_format_string;8608 using namespace analyze_printf;8609 8610 // Now type check the data expression that matches the8611 // format specifier.8612 const analyze_printf::ArgType &AT = FS.getArgType(S.Context, isObjCContext());8613 if (!AT.isValid())8614 return true;8615 8616 QualType ExprTy = E->getType();8617 while (const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {8618 ExprTy = TET->getUnderlyingExpr()->getType();8619 }8620 8621 // When using the format attribute in C++, you can receive a function or an8622 // array that will necessarily decay to a pointer when passed to the final8623 // format consumer. Apply decay before type comparison.8624 if (ExprTy->canDecayToPointerType())8625 ExprTy = S.Context.getDecayedType(ExprTy);8626 8627 // Diagnose attempts to print a boolean value as a character. Unlike other8628 // -Wformat diagnostics, this is fine from a type perspective, but it still8629 // doesn't make sense.8630 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&8631 E->isKnownToHaveBooleanValue()) {8632 const CharSourceRange &CSR =8633 getSpecifierRange(StartSpecifier, SpecifierLen);8634 SmallString<4> FSString;8635 llvm::raw_svector_ostream os(FSString);8636 FS.toString(os);8637 EmitFormatDiagnostic(S.PDiag(diag::warn_format_bool_as_character)8638 << FSString,8639 E->getExprLoc(), false, CSR);8640 return true;8641 }8642 8643 // Diagnose attempts to use '%P' with ObjC object types, which will result in8644 // dumping raw class data (like is-a pointer), not actual data.8645 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&8646 ExprTy->isObjCObjectPointerType()) {8647 const CharSourceRange &CSR =8648 getSpecifierRange(StartSpecifier, SpecifierLen);8649 EmitFormatDiagnostic(S.PDiag(diag::warn_format_P_with_objc_pointer),8650 E->getExprLoc(), false, CSR);8651 return true;8652 }8653 8654 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;8655 ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy);8656 ArgType::MatchKind OrigMatch = Match;8657 8658 Match = handleFormatSignedness(Match, S.getDiagnostics(), E->getExprLoc());8659 if (Match == ArgType::Match)8660 return true;8661 8662 // NoMatchPromotionTypeConfusion should be only returned in ImplictCastExpr8663 assert(Match != ArgType::NoMatchPromotionTypeConfusion);8664 8665 // Look through argument promotions for our error message's reported type.8666 // This includes the integral and floating promotions, but excludes array8667 // and function pointer decay (seeing that an argument intended to be a8668 // string has type 'char [6]' is probably more confusing than 'char *') and8669 // certain bitfield promotions (bitfields can be 'demoted' to a lesser type).8670 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {8671 if (isArithmeticArgumentPromotion(S, ICE)) {8672 E = ICE->getSubExpr();8673 ExprTy = E->getType();8674 8675 // Check if we didn't match because of an implicit cast from a 'char'8676 // or 'short' to an 'int'. This is done because printf is a varargs8677 // function.8678 if (ICE->getType() == S.Context.IntTy ||8679 ICE->getType() == S.Context.UnsignedIntTy) {8680 // All further checking is done on the subexpression8681 ImplicitMatch = AT.matchesType(S.Context, ExprTy);8682 if (OrigMatch == ArgType::NoMatchSignedness &&8683 ImplicitMatch != ArgType::NoMatchSignedness)8684 // If the original match was a signedness match this match on the8685 // implicit cast type also need to be signedness match otherwise we8686 // might introduce new unexpected warnings from -Wformat-signedness.8687 return true;8688 ImplicitMatch = handleFormatSignedness(8689 ImplicitMatch, S.getDiagnostics(), E->getExprLoc());8690 if (ImplicitMatch == ArgType::Match)8691 return true;8692 }8693 }8694 } else if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) {8695 // Special case for 'a', which has type 'int' in C.8696 // Note, however, that we do /not/ want to treat multibyte constants like8697 // 'MooV' as characters! This form is deprecated but still exists. In8698 // addition, don't treat expressions as of type 'char' if one byte length8699 // modifier is provided.8700 if (ExprTy == S.Context.IntTy &&8701 FS.getLengthModifier().getKind() != LengthModifier::AsChar)8702 if (llvm::isUIntN(S.Context.getCharWidth(), CL->getValue())) {8703 ExprTy = S.Context.CharTy;8704 // To improve check results, we consider a character literal in C8705 // to be a 'char' rather than an 'int'. 'printf("%hd", 'a');' is8706 // more likely a type confusion situation, so we will suggest to8707 // use '%hhd' instead by discarding the MatchPromotion.8708 if (Match == ArgType::MatchPromotion)8709 Match = ArgType::NoMatch;8710 }8711 }8712 if (Match == ArgType::MatchPromotion) {8713 // WG14 N2562 only clarified promotions in *printf8714 // For NSLog in ObjC, just preserve -Wformat behavior8715 if (!S.getLangOpts().ObjC &&8716 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&8717 ImplicitMatch != ArgType::NoMatchTypeConfusion)8718 return true;8719 Match = ArgType::NoMatch;8720 }8721 if (ImplicitMatch == ArgType::NoMatchPedantic ||8722 ImplicitMatch == ArgType::NoMatchTypeConfusion)8723 Match = ImplicitMatch;8724 assert(Match != ArgType::MatchPromotion);8725 8726 // Look through unscoped enums to their underlying type.8727 bool IsEnum = false;8728 bool IsScopedEnum = false;8729 QualType IntendedTy = ExprTy;8730 if (const auto *ED = ExprTy->getAsEnumDecl()) {8731 IntendedTy = ED->getIntegerType();8732 if (!ED->isScoped()) {8733 ExprTy = IntendedTy;8734 // This controls whether we're talking about the underlying type or not,8735 // which we only want to do when it's an unscoped enum.8736 IsEnum = true;8737 } else {8738 IsScopedEnum = true;8739 }8740 }8741 8742 // %C in an Objective-C context prints a unichar, not a wchar_t.8743 // If the argument is an integer of some kind, believe the %C and suggest8744 // a cast instead of changing the conversion specifier.8745 if (isObjCContext() &&8746 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {8747 if (ExprTy->isIntegralOrUnscopedEnumerationType() &&8748 !ExprTy->isCharType()) {8749 // 'unichar' is defined as a typedef of unsigned short, but we should8750 // prefer using the typedef if it is visible.8751 IntendedTy = S.Context.UnsignedShortTy;8752 8753 // While we are here, check if the value is an IntegerLiteral that happens8754 // to be within the valid range.8755 if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) {8756 const llvm::APInt &V = IL->getValue();8757 if (V.getActiveBits() <= S.Context.getTypeSize(IntendedTy))8758 return true;8759 }8760 8761 LookupResult Result(S, &S.Context.Idents.get("unichar"), E->getBeginLoc(),8762 Sema::LookupOrdinaryName);8763 if (S.LookupName(Result, S.getCurScope())) {8764 NamedDecl *ND = Result.getFoundDecl();8765 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND))8766 if (TD->getUnderlyingType() == IntendedTy)8767 IntendedTy =8768 S.Context.getTypedefType(ElaboratedTypeKeyword::None,8769 /*Qualifier=*/std::nullopt, TD);8770 }8771 }8772 }8773 8774 // Special-case some of Darwin's platform-independence types by suggesting8775 // casts to primitive types that are known to be large enough.8776 bool ShouldNotPrintDirectly = false; StringRef CastTyName;8777 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {8778 QualType CastTy;8779 std::tie(CastTy, CastTyName) = shouldNotPrintDirectly(S.Context, IntendedTy, E);8780 if (!CastTy.isNull()) {8781 // %zi/%zu and %td/%tu are OK to use for NSInteger/NSUInteger of type int8782 // (long in ASTContext). Only complain to pedants or when they're the8783 // underlying type of a scoped enum (which always needs a cast).8784 if (!IsScopedEnum &&8785 (CastTyName == "NSInteger" || CastTyName == "NSUInteger") &&8786 (AT.isSizeT() || AT.isPtrdiffT()) &&8787 AT.matchesType(S.Context, CastTy))8788 Match = ArgType::NoMatchPedantic;8789 IntendedTy = CastTy;8790 ShouldNotPrintDirectly = true;8791 }8792 }8793 8794 // We may be able to offer a FixItHint if it is a supported type.8795 PrintfSpecifier fixedFS = FS;8796 bool Success =8797 fixedFS.fixType(IntendedTy, S.getLangOpts(), S.Context, isObjCContext());8798 8799 if (Success) {8800 // Get the fix string from the fixed format specifier8801 SmallString<16> buf;8802 llvm::raw_svector_ostream os(buf);8803 fixedFS.toString(os);8804 8805 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);8806 8807 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {8808 unsigned Diag;8809 switch (Match) {8810 case ArgType::Match:8811 case ArgType::MatchPromotion:8812 case ArgType::NoMatchPromotionTypeConfusion:8813 llvm_unreachable("expected non-matching");8814 case ArgType::NoMatchSignedness:8815 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;8816 break;8817 case ArgType::NoMatchPedantic:8818 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;8819 break;8820 case ArgType::NoMatchTypeConfusion:8821 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;8822 break;8823 case ArgType::NoMatch:8824 Diag = diag::warn_format_conversion_argument_type_mismatch;8825 break;8826 }8827 8828 // In this case, the specifier is wrong and should be changed to match8829 // the argument.8830 EmitFormatDiagnostic(S.PDiag(Diag)8831 << AT.getRepresentativeTypeName(S.Context)8832 << IntendedTy << IsEnum << E->getSourceRange(),8833 E->getBeginLoc(),8834 /*IsStringLocation*/ false, SpecRange,8835 FixItHint::CreateReplacement(SpecRange, os.str()));8836 } else {8837 // The canonical type for formatting this value is different from the8838 // actual type of the expression. (This occurs, for example, with Darwin's8839 // NSInteger on 32-bit platforms, where it is typedef'd as 'int', but8840 // should be printed as 'long' for 64-bit compatibility.)8841 // Rather than emitting a normal format/argument mismatch, we want to8842 // add a cast to the recommended type (and correct the format string8843 // if necessary). We should also do so for scoped enumerations.8844 SmallString<16> CastBuf;8845 llvm::raw_svector_ostream CastFix(CastBuf);8846 CastFix << (S.LangOpts.CPlusPlus ? "static_cast<" : "(");8847 IntendedTy.print(CastFix, S.Context.getPrintingPolicy());8848 CastFix << (S.LangOpts.CPlusPlus ? ">" : ")");8849 8850 SmallVector<FixItHint,4> Hints;8851 ArgType::MatchKind IntendedMatch = AT.matchesType(S.Context, IntendedTy);8852 IntendedMatch = handleFormatSignedness(IntendedMatch, S.getDiagnostics(),8853 E->getExprLoc());8854 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)8855 Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));8856 8857 if (const CStyleCastExpr *CCast = dyn_cast<CStyleCastExpr>(E)) {8858 // If there's already a cast present, just replace it.8859 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());8860 Hints.push_back(FixItHint::CreateReplacement(CastRange, CastFix.str()));8861 8862 } else if (!requiresParensToAddCast(E) && !S.LangOpts.CPlusPlus) {8863 // If the expression has high enough precedence,8864 // just write the C-style cast.8865 Hints.push_back(8866 FixItHint::CreateInsertion(E->getBeginLoc(), CastFix.str()));8867 } else {8868 // Otherwise, add parens around the expression as well as the cast.8869 CastFix << "(";8870 Hints.push_back(8871 FixItHint::CreateInsertion(E->getBeginLoc(), CastFix.str()));8872 8873 // We don't use getLocForEndOfToken because it returns invalid source8874 // locations for macro expansions (by design).8875 SourceLocation EndLoc = S.SourceMgr.getSpellingLoc(E->getEndLoc());8876 SourceLocation After = EndLoc.getLocWithOffset(8877 Lexer::MeasureTokenLength(EndLoc, S.SourceMgr, S.LangOpts));8878 Hints.push_back(FixItHint::CreateInsertion(After, ")"));8879 }8880 8881 if (ShouldNotPrintDirectly && !IsScopedEnum) {8882 // The expression has a type that should not be printed directly.8883 // We extract the name from the typedef because we don't want to show8884 // the underlying type in the diagnostic.8885 StringRef Name;8886 if (const auto *TypedefTy = ExprTy->getAs<TypedefType>())8887 Name = TypedefTy->getDecl()->getName();8888 else8889 Name = CastTyName;8890 unsigned Diag = Match == ArgType::NoMatchPedantic8891 ? diag::warn_format_argument_needs_cast_pedantic8892 : diag::warn_format_argument_needs_cast;8893 EmitFormatDiagnostic(S.PDiag(Diag) << Name << IntendedTy << IsEnum8894 << E->getSourceRange(),8895 E->getBeginLoc(), /*IsStringLocation=*/false,8896 SpecRange, Hints);8897 } else {8898 // In this case, the expression could be printed using a different8899 // specifier, but we've decided that the specifier is probably correct8900 // and we should cast instead. Just use the normal warning message.8901 8902 unsigned Diag =8903 IsScopedEnum8904 ? diag::warn_format_conversion_argument_type_mismatch_pedantic8905 : diag::warn_format_conversion_argument_type_mismatch;8906 8907 EmitFormatDiagnostic(8908 S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy8909 << IsEnum << E->getSourceRange(),8910 E->getBeginLoc(), /*IsStringLocation*/ false, SpecRange, Hints);8911 }8912 }8913 } else {8914 const CharSourceRange &CSR = getSpecifierRange(StartSpecifier,8915 SpecifierLen);8916 // Since the warning for passing non-POD types to variadic functions8917 // was deferred until now, we emit a warning for non-POD8918 // arguments here.8919 bool EmitTypeMismatch = false;8920 switch (S.isValidVarArgType(ExprTy)) {8921 case VarArgKind::Valid:8922 case VarArgKind::ValidInCXX11: {8923 unsigned Diag;8924 switch (Match) {8925 case ArgType::Match:8926 case ArgType::MatchPromotion:8927 case ArgType::NoMatchPromotionTypeConfusion:8928 llvm_unreachable("expected non-matching");8929 case ArgType::NoMatchSignedness:8930 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;8931 break;8932 case ArgType::NoMatchPedantic:8933 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;8934 break;8935 case ArgType::NoMatchTypeConfusion:8936 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;8937 break;8938 case ArgType::NoMatch:8939 Diag = isInvalidOSLogArgTypeForCodeGen(FSType, ExprTy)8940 ? diag::err_format_conversion_argument_type_mismatch8941 : diag::warn_format_conversion_argument_type_mismatch;8942 break;8943 }8944 8945 EmitFormatDiagnostic(8946 S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy8947 << IsEnum << CSR << E->getSourceRange(),8948 E->getBeginLoc(), /*IsStringLocation*/ false, CSR);8949 break;8950 }8951 case VarArgKind::Undefined:8952 case VarArgKind::MSVCUndefined:8953 if (CallType == VariadicCallType::DoesNotApply) {8954 EmitTypeMismatch = true;8955 } else {8956 EmitFormatDiagnostic(8957 S.PDiag(diag::warn_non_pod_vararg_with_format_string)8958 << S.getLangOpts().CPlusPlus11 << ExprTy << CallType8959 << AT.getRepresentativeTypeName(S.Context) << CSR8960 << E->getSourceRange(),8961 E->getBeginLoc(), /*IsStringLocation*/ false, CSR);8962 checkForCStrMembers(AT, E);8963 }8964 break;8965 8966 case VarArgKind::Invalid:8967 if (CallType == VariadicCallType::DoesNotApply)8968 EmitTypeMismatch = true;8969 else if (ExprTy->isObjCObjectType())8970 EmitFormatDiagnostic(8971 S.PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)8972 << S.getLangOpts().CPlusPlus11 << ExprTy << CallType8973 << AT.getRepresentativeTypeName(S.Context) << CSR8974 << E->getSourceRange(),8975 E->getBeginLoc(), /*IsStringLocation*/ false, CSR);8976 else8977 // FIXME: If this is an initializer list, suggest removing the braces8978 // or inserting a cast to the target type.8979 S.Diag(E->getBeginLoc(), diag::err_cannot_pass_to_vararg_format)8980 << isa<InitListExpr>(E) << ExprTy << CallType8981 << AT.getRepresentativeTypeName(S.Context) << E->getSourceRange();8982 break;8983 }8984 8985 if (EmitTypeMismatch) {8986 // The function is not variadic, so we do not generate warnings about8987 // being allowed to pass that object as a variadic argument. Instead,8988 // since there are inherently no printf specifiers for types which cannot8989 // be passed as variadic arguments, emit a plain old specifier mismatch8990 // argument.8991 EmitFormatDiagnostic(8992 S.PDiag(diag::warn_format_conversion_argument_type_mismatch)8993 << AT.getRepresentativeTypeName(S.Context) << ExprTy << false8994 << E->getSourceRange(),8995 E->getBeginLoc(), false, CSR);8996 }8997 8998 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&8999 "format string specifier index out of range");9000 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] = true;9001 }9002 9003 return true;9004}9005 9006//===--- CHECK: Scanf format string checking ------------------------------===//9007 9008namespace {9009 9010class CheckScanfHandler : public CheckFormatHandler {9011public:9012 CheckScanfHandler(Sema &s, const FormatStringLiteral *fexpr,9013 const Expr *origFormatExpr, FormatStringType type,9014 unsigned firstDataArg, unsigned numDataArgs,9015 const char *beg, Sema::FormatArgumentPassingKind APK,9016 ArrayRef<const Expr *> Args, unsigned formatIdx,9017 bool inFunctionCall, VariadicCallType CallType,9018 llvm::SmallBitVector &CheckedVarArgs,9019 UncoveredArgHandler &UncoveredArg)9020 : CheckFormatHandler(s, fexpr, origFormatExpr, type, firstDataArg,9021 numDataArgs, beg, APK, Args, formatIdx,9022 inFunctionCall, CallType, CheckedVarArgs,9023 UncoveredArg) {}9024 9025 bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,9026 const char *startSpecifier,9027 unsigned specifierLen) override;9028 9029 bool HandleInvalidScanfConversionSpecifier(9030 const analyze_scanf::ScanfSpecifier &FS,9031 const char *startSpecifier,9032 unsigned specifierLen) override;9033 9034 void HandleIncompleteScanList(const char *start, const char *end) override;9035};9036 9037} // namespace9038 9039void CheckScanfHandler::HandleIncompleteScanList(const char *start,9040 const char *end) {9041 EmitFormatDiagnostic(S.PDiag(diag::warn_scanf_scanlist_incomplete),9042 getLocationOfByte(end), /*IsStringLocation*/true,9043 getSpecifierRange(start, end - start));9044}9045 9046bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(9047 const analyze_scanf::ScanfSpecifier &FS,9048 const char *startSpecifier,9049 unsigned specifierLen) {9050 const analyze_scanf::ScanfConversionSpecifier &CS =9051 FS.getConversionSpecifier();9052 9053 return HandleInvalidConversionSpecifier(FS.getArgIndex(),9054 getLocationOfByte(CS.getStart()),9055 startSpecifier, specifierLen,9056 CS.getStart(), CS.getLength());9057}9058 9059bool CheckScanfHandler::HandleScanfSpecifier(9060 const analyze_scanf::ScanfSpecifier &FS,9061 const char *startSpecifier,9062 unsigned specifierLen) {9063 using namespace analyze_scanf;9064 using namespace analyze_format_string;9065 9066 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();9067 9068 // Handle case where '%' and '*' don't consume an argument. These shouldn't9069 // be used to decide if we are using positional arguments consistently.9070 if (FS.consumesDataArgument()) {9071 if (atFirstArg) {9072 atFirstArg = false;9073 usesPositionalArgs = FS.usesPositionalArg();9074 }9075 else if (usesPositionalArgs != FS.usesPositionalArg()) {9076 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),9077 startSpecifier, specifierLen);9078 return false;9079 }9080 }9081 9082 // Check if the field with is non-zero.9083 const OptionalAmount &Amt = FS.getFieldWidth();9084 if (Amt.getHowSpecified() == OptionalAmount::Constant) {9085 if (Amt.getConstantAmount() == 0) {9086 const CharSourceRange &R = getSpecifierRange(Amt.getStart(),9087 Amt.getConstantLength());9088 EmitFormatDiagnostic(S.PDiag(diag::warn_scanf_nonzero_width),9089 getLocationOfByte(Amt.getStart()),9090 /*IsStringLocation*/true, R,9091 FixItHint::CreateRemoval(R));9092 }9093 }9094 9095 if (!FS.consumesDataArgument()) {9096 // FIXME: Technically specifying a precision or field width here9097 // makes no sense. Worth issuing a warning at some point.9098 return true;9099 }9100 9101 // Consume the argument.9102 unsigned argIndex = FS.getArgIndex();9103 if (argIndex < NumDataArgs) {9104 // The check to see if the argIndex is valid will come later.9105 // We set the bit here because we may exit early from this9106 // function if we encounter some other error.9107 CoveredArgs.set(argIndex);9108 }9109 9110 // Check the length modifier is valid with the given conversion specifier.9111 if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),9112 S.getLangOpts()))9113 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,9114 diag::warn_format_nonsensical_length);9115 else if (!FS.hasStandardLengthModifier())9116 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);9117 else if (!FS.hasStandardLengthConversionCombination())9118 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,9119 diag::warn_format_non_standard_conversion_spec);9120 9121 if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))9122 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);9123 9124 // The remaining checks depend on the data arguments.9125 if (!HasFormatArguments())9126 return true;9127 9128 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))9129 return false;9130 9131 // Check that the argument type matches the format specifier.9132 const Expr *Ex = getDataArg(argIndex);9133 if (!Ex)9134 return true;9135 9136 const analyze_format_string::ArgType &AT = FS.getArgType(S.Context);9137 9138 if (!AT.isValid()) {9139 return true;9140 }9141 9142 analyze_format_string::ArgType::MatchKind Match =9143 AT.matchesType(S.Context, Ex->getType());9144 Match = handleFormatSignedness(Match, S.getDiagnostics(), Ex->getExprLoc());9145 if (Match == analyze_format_string::ArgType::Match)9146 return true;9147 bool Pedantic = Match == analyze_format_string::ArgType::NoMatchPedantic;9148 bool Signedness = Match == analyze_format_string::ArgType::NoMatchSignedness;9149 9150 ScanfSpecifier fixedFS = FS;9151 bool Success = fixedFS.fixType(Ex->getType(), Ex->IgnoreImpCasts()->getType(),9152 S.getLangOpts(), S.Context);9153 9154 unsigned Diag =9155 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic9156 : Signedness9157 ? diag::warn_format_conversion_argument_type_mismatch_signedness9158 : diag::warn_format_conversion_argument_type_mismatch;9159 9160 if (Success) {9161 // Get the fix string from the fixed format specifier.9162 SmallString<128> buf;9163 llvm::raw_svector_ostream os(buf);9164 fixedFS.toString(os);9165 9166 EmitFormatDiagnostic(9167 S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context)9168 << Ex->getType() << false << Ex->getSourceRange(),9169 Ex->getBeginLoc(),9170 /*IsStringLocation*/ false,9171 getSpecifierRange(startSpecifier, specifierLen),9172 FixItHint::CreateReplacement(9173 getSpecifierRange(startSpecifier, specifierLen), os.str()));9174 } else {9175 EmitFormatDiagnostic(S.PDiag(Diag)9176 << AT.getRepresentativeTypeName(S.Context)9177 << Ex->getType() << false << Ex->getSourceRange(),9178 Ex->getBeginLoc(),9179 /*IsStringLocation*/ false,9180 getSpecifierRange(startSpecifier, specifierLen));9181 }9182 9183 return true;9184}9185 9186static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref,9187 ArrayRef<EquatableFormatArgument> RefArgs,9188 const StringLiteral *Fmt,9189 ArrayRef<EquatableFormatArgument> FmtArgs,9190 const Expr *FmtExpr, bool InFunctionCall) {9191 bool HadError = false;9192 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();9193 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();9194 while (FmtIter < FmtEnd && RefIter < RefEnd) {9195 // In positional-style format strings, the same specifier can appear9196 // multiple times (like %2$i %2$d). Specifiers in both RefArgs and FmtArgs9197 // are sorted by getPosition(), and we process each range of equal9198 // getPosition() values as one group.9199 // RefArgs are taken from a string literal that was given to9200 // attribute(format_matches), and if we got this far, we have already9201 // verified that if it has positional specifiers that appear in multiple9202 // locations, then they are all mutually compatible. What's left for us to9203 // do is verify that all specifiers with the same position in FmtArgs are9204 // compatible with the RefArgs specifiers. We check each specifier from9205 // FmtArgs against the first member of the RefArgs group.9206 for (; FmtIter < FmtEnd; ++FmtIter) {9207 // Clang does not diagnose missing format specifiers in positional-style9208 // strings (TODO: which it probably should do, as it is UB to skip over a9209 // format argument). Skip specifiers if needed.9210 if (FmtIter->getPosition() < RefIter->getPosition())9211 continue;9212 9213 // Delimits a new getPosition() value.9214 if (FmtIter->getPosition() > RefIter->getPosition())9215 break;9216 9217 HadError |=9218 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);9219 }9220 9221 // Jump RefIter to the start of the next group.9222 RefIter = std::find_if(RefIter + 1, RefEnd, [=](const auto &Arg) {9223 return Arg.getPosition() != RefIter->getPosition();9224 });9225 }9226 9227 if (FmtIter < FmtEnd) {9228 CheckFormatHandler::EmitFormatDiagnostic(9229 S, InFunctionCall, FmtExpr,9230 S.PDiag(diag::warn_format_cmp_specifier_arity) << 1,9231 FmtExpr->getBeginLoc(), false, FmtIter->getSourceRange());9232 HadError = S.Diag(Ref->getBeginLoc(), diag::note_format_cmp_with) << 1;9233 } else if (RefIter < RefEnd) {9234 CheckFormatHandler::EmitFormatDiagnostic(9235 S, InFunctionCall, FmtExpr,9236 S.PDiag(diag::warn_format_cmp_specifier_arity) << 0,9237 FmtExpr->getBeginLoc(), false, Fmt->getSourceRange());9238 HadError = S.Diag(Ref->getBeginLoc(), diag::note_format_cmp_with)9239 << 1 << RefIter->getSourceRange();9240 }9241 return !HadError;9242}9243 9244static void CheckFormatString(9245 Sema &S, const FormatStringLiteral *FExpr,9246 const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr,9247 ArrayRef<const Expr *> Args, Sema::FormatArgumentPassingKind APK,9248 unsigned format_idx, unsigned firstDataArg, FormatStringType Type,9249 bool inFunctionCall, VariadicCallType CallType,9250 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,9251 bool IgnoreStringsWithoutSpecifiers) {9252 // CHECK: is the format string a wide literal?9253 if (!FExpr->isAscii() && !FExpr->isUTF8()) {9254 CheckFormatHandler::EmitFormatDiagnostic(9255 S, inFunctionCall, Args[format_idx],9256 S.PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),9257 /*IsStringLocation*/ true, OrigFormatExpr->getSourceRange());9258 return;9259 }9260 9261 // Str - The format string. NOTE: this is NOT null-terminated!9262 StringRef StrRef = FExpr->getString();9263 const char *Str = StrRef.data();9264 // Account for cases where the string literal is truncated in a declaration.9265 const ConstantArrayType *T =9266 S.Context.getAsConstantArrayType(FExpr->getType());9267 assert(T && "String literal not of constant array type!");9268 size_t TypeSize = T->getZExtSize();9269 size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size());9270 const unsigned numDataArgs = Args.size() - firstDataArg;9271 9272 if (IgnoreStringsWithoutSpecifiers &&9273 !analyze_format_string::parseFormatStringHasFormattingSpecifiers(9274 Str, Str + StrLen, S.getLangOpts(), S.Context.getTargetInfo()))9275 return;9276 9277 // Emit a warning if the string literal is truncated and does not contain an9278 // embedded null character.9279 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains('\0')) {9280 CheckFormatHandler::EmitFormatDiagnostic(9281 S, inFunctionCall, Args[format_idx],9282 S.PDiag(diag::warn_printf_format_string_not_null_terminated),9283 FExpr->getBeginLoc(),9284 /*IsStringLocation=*/true, OrigFormatExpr->getSourceRange());9285 return;9286 }9287 9288 // CHECK: empty format string?9289 if (StrLen == 0 && numDataArgs > 0) {9290 CheckFormatHandler::EmitFormatDiagnostic(9291 S, inFunctionCall, Args[format_idx],9292 S.PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),9293 /*IsStringLocation*/ true, OrigFormatExpr->getSourceRange());9294 return;9295 }9296 9297 if (Type == FormatStringType::Printf || Type == FormatStringType::NSString ||9298 Type == FormatStringType::Kprintf ||9299 Type == FormatStringType::FreeBSDKPrintf ||9300 Type == FormatStringType::OSLog || Type == FormatStringType::OSTrace) {9301 bool IsObjC =9302 Type == FormatStringType::NSString || Type == FormatStringType::OSTrace;9303 if (ReferenceFormatString == nullptr) {9304 CheckPrintfHandler H(S, FExpr, OrigFormatExpr, Type, firstDataArg,9305 numDataArgs, IsObjC, Str, APK, Args, format_idx,9306 inFunctionCall, CallType, CheckedVarArgs,9307 UncoveredArg);9308 9309 if (!analyze_format_string::ParsePrintfString(9310 H, Str, Str + StrLen, S.getLangOpts(), S.Context.getTargetInfo(),9311 Type == FormatStringType::Kprintf ||9312 Type == FormatStringType::FreeBSDKPrintf))9313 H.DoneProcessing();9314 } else {9315 S.CheckFormatStringsCompatible(9316 Type, ReferenceFormatString, FExpr->getFormatString(),9317 inFunctionCall ? nullptr : Args[format_idx]);9318 }9319 } else if (Type == FormatStringType::Scanf) {9320 CheckScanfHandler H(S, FExpr, OrigFormatExpr, Type, firstDataArg,9321 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,9322 CallType, CheckedVarArgs, UncoveredArg);9323 9324 if (!analyze_format_string::ParseScanfString(9325 H, Str, Str + StrLen, S.getLangOpts(), S.Context.getTargetInfo()))9326 H.DoneProcessing();9327 } // TODO: handle other formats9328}9329 9330bool Sema::CheckFormatStringsCompatible(9331 FormatStringType Type, const StringLiteral *AuthoritativeFormatString,9332 const StringLiteral *TestedFormatString, const Expr *FunctionCallArg) {9333 if (Type != FormatStringType::Printf && Type != FormatStringType::NSString &&9334 Type != FormatStringType::Kprintf &&9335 Type != FormatStringType::FreeBSDKPrintf &&9336 Type != FormatStringType::OSLog && Type != FormatStringType::OSTrace)9337 return true;9338 9339 bool IsObjC =9340 Type == FormatStringType::NSString || Type == FormatStringType::OSTrace;9341 llvm::SmallVector<EquatableFormatArgument, 9> RefArgs, FmtArgs;9342 FormatStringLiteral RefLit = AuthoritativeFormatString;9343 FormatStringLiteral TestLit = TestedFormatString;9344 const Expr *Arg;9345 bool DiagAtStringLiteral;9346 if (FunctionCallArg) {9347 Arg = FunctionCallArg;9348 DiagAtStringLiteral = false;9349 } else {9350 Arg = TestedFormatString;9351 DiagAtStringLiteral = true;9352 }9353 if (DecomposePrintfHandler::GetSpecifiers(*this, &RefLit,9354 AuthoritativeFormatString, Type,9355 IsObjC, true, RefArgs) &&9356 DecomposePrintfHandler::GetSpecifiers(*this, &TestLit, Arg, Type, IsObjC,9357 DiagAtStringLiteral, FmtArgs)) {9358 return CompareFormatSpecifiers(*this, AuthoritativeFormatString, RefArgs,9359 TestedFormatString, FmtArgs, Arg,9360 DiagAtStringLiteral);9361 }9362 return false;9363}9364 9365bool Sema::ValidateFormatString(FormatStringType Type,9366 const StringLiteral *Str) {9367 if (Type != FormatStringType::Printf && Type != FormatStringType::NSString &&9368 Type != FormatStringType::Kprintf &&9369 Type != FormatStringType::FreeBSDKPrintf &&9370 Type != FormatStringType::OSLog && Type != FormatStringType::OSTrace)9371 return true;9372 9373 FormatStringLiteral RefLit = Str;9374 llvm::SmallVector<EquatableFormatArgument, 9> Args;9375 bool IsObjC =9376 Type == FormatStringType::NSString || Type == FormatStringType::OSTrace;9377 if (!DecomposePrintfHandler::GetSpecifiers(*this, &RefLit, Str, Type, IsObjC,9378 true, Args))9379 return false;9380 9381 // Group arguments by getPosition() value, and check that each member of the9382 // group is compatible with the first member. This verifies that when9383 // positional arguments are used multiple times (such as %2$i %2$d), all uses9384 // are mutually compatible. As an optimization, don't test the first member9385 // against itself.9386 bool HadError = false;9387 auto Iter = Args.begin();9388 auto End = Args.end();9389 while (Iter != End) {9390 const auto &FirstInGroup = *Iter;9391 for (++Iter;9392 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();9393 ++Iter) {9394 HadError |= !Iter->VerifyCompatible(*this, FirstInGroup, Str, true);9395 }9396 }9397 return !HadError;9398}9399 9400bool Sema::FormatStringHasSArg(const StringLiteral *FExpr) {9401 // Str - The format string. NOTE: this is NOT null-terminated!9402 StringRef StrRef = FExpr->getString();9403 const char *Str = StrRef.data();9404 // Account for cases where the string literal is truncated in a declaration.9405 const ConstantArrayType *T = Context.getAsConstantArrayType(FExpr->getType());9406 assert(T && "String literal not of constant array type!");9407 size_t TypeSize = T->getZExtSize();9408 size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size());9409 return analyze_format_string::ParseFormatStringHasSArg(Str, Str + StrLen,9410 getLangOpts(),9411 Context.getTargetInfo());9412}9413 9414//===--- CHECK: Warn on use of wrong absolute value function. -------------===//9415 9416// Returns the related absolute value function that is larger, of 0 if one9417// does not exist.9418static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction) {9419 switch (AbsFunction) {9420 default:9421 return 0;9422 9423 case Builtin::BI__builtin_abs:9424 return Builtin::BI__builtin_labs;9425 case Builtin::BI__builtin_labs:9426 return Builtin::BI__builtin_llabs;9427 case Builtin::BI__builtin_llabs:9428 return 0;9429 9430 case Builtin::BI__builtin_fabsf:9431 return Builtin::BI__builtin_fabs;9432 case Builtin::BI__builtin_fabs:9433 return Builtin::BI__builtin_fabsl;9434 case Builtin::BI__builtin_fabsl:9435 return 0;9436 9437 case Builtin::BI__builtin_cabsf:9438 return Builtin::BI__builtin_cabs;9439 case Builtin::BI__builtin_cabs:9440 return Builtin::BI__builtin_cabsl;9441 case Builtin::BI__builtin_cabsl:9442 return 0;9443 9444 case Builtin::BIabs:9445 return Builtin::BIlabs;9446 case Builtin::BIlabs:9447 return Builtin::BIllabs;9448 case Builtin::BIllabs:9449 return 0;9450 9451 case Builtin::BIfabsf:9452 return Builtin::BIfabs;9453 case Builtin::BIfabs:9454 return Builtin::BIfabsl;9455 case Builtin::BIfabsl:9456 return 0;9457 9458 case Builtin::BIcabsf:9459 return Builtin::BIcabs;9460 case Builtin::BIcabs:9461 return Builtin::BIcabsl;9462 case Builtin::BIcabsl:9463 return 0;9464 }9465}9466 9467// Returns the argument type of the absolute value function.9468static QualType getAbsoluteValueArgumentType(ASTContext &Context,9469 unsigned AbsType) {9470 if (AbsType == 0)9471 return QualType();9472 9473 ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None;9474 QualType BuiltinType = Context.GetBuiltinType(AbsType, Error);9475 if (Error != ASTContext::GE_None)9476 return QualType();9477 9478 const FunctionProtoType *FT = BuiltinType->getAs<FunctionProtoType>();9479 if (!FT)9480 return QualType();9481 9482 if (FT->getNumParams() != 1)9483 return QualType();9484 9485 return FT->getParamType(0);9486}9487 9488// Returns the best absolute value function, or zero, based on type and9489// current absolute value function.9490static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType,9491 unsigned AbsFunctionKind) {9492 unsigned BestKind = 0;9493 uint64_t ArgSize = Context.getTypeSize(ArgType);9494 for (unsigned Kind = AbsFunctionKind; Kind != 0;9495 Kind = getLargerAbsoluteValueFunction(Kind)) {9496 QualType ParamType = getAbsoluteValueArgumentType(Context, Kind);9497 if (Context.getTypeSize(ParamType) >= ArgSize) {9498 if (BestKind == 0)9499 BestKind = Kind;9500 else if (Context.hasSameType(ParamType, ArgType)) {9501 BestKind = Kind;9502 break;9503 }9504 }9505 }9506 return BestKind;9507}9508 9509enum AbsoluteValueKind {9510 AVK_Integer,9511 AVK_Floating,9512 AVK_Complex9513};9514 9515static AbsoluteValueKind getAbsoluteValueKind(QualType T) {9516 if (T->isIntegralOrEnumerationType())9517 return AVK_Integer;9518 if (T->isRealFloatingType())9519 return AVK_Floating;9520 if (T->isAnyComplexType())9521 return AVK_Complex;9522 9523 llvm_unreachable("Type not integer, floating, or complex");9524}9525 9526// Changes the absolute value function to a different type. Preserves whether9527// the function is a builtin.9528static unsigned changeAbsFunction(unsigned AbsKind,9529 AbsoluteValueKind ValueKind) {9530 switch (ValueKind) {9531 case AVK_Integer:9532 switch (AbsKind) {9533 default:9534 return 0;9535 case Builtin::BI__builtin_fabsf:9536 case Builtin::BI__builtin_fabs:9537 case Builtin::BI__builtin_fabsl:9538 case Builtin::BI__builtin_cabsf:9539 case Builtin::BI__builtin_cabs:9540 case Builtin::BI__builtin_cabsl:9541 return Builtin::BI__builtin_abs;9542 case Builtin::BIfabsf:9543 case Builtin::BIfabs:9544 case Builtin::BIfabsl:9545 case Builtin::BIcabsf:9546 case Builtin::BIcabs:9547 case Builtin::BIcabsl:9548 return Builtin::BIabs;9549 }9550 case AVK_Floating:9551 switch (AbsKind) {9552 default:9553 return 0;9554 case Builtin::BI__builtin_abs:9555 case Builtin::BI__builtin_labs:9556 case Builtin::BI__builtin_llabs:9557 case Builtin::BI__builtin_cabsf:9558 case Builtin::BI__builtin_cabs:9559 case Builtin::BI__builtin_cabsl:9560 return Builtin::BI__builtin_fabsf;9561 case Builtin::BIabs:9562 case Builtin::BIlabs:9563 case Builtin::BIllabs:9564 case Builtin::BIcabsf:9565 case Builtin::BIcabs:9566 case Builtin::BIcabsl:9567 return Builtin::BIfabsf;9568 }9569 case AVK_Complex:9570 switch (AbsKind) {9571 default:9572 return 0;9573 case Builtin::BI__builtin_abs:9574 case Builtin::BI__builtin_labs:9575 case Builtin::BI__builtin_llabs:9576 case Builtin::BI__builtin_fabsf:9577 case Builtin::BI__builtin_fabs:9578 case Builtin::BI__builtin_fabsl:9579 return Builtin::BI__builtin_cabsf;9580 case Builtin::BIabs:9581 case Builtin::BIlabs:9582 case Builtin::BIllabs:9583 case Builtin::BIfabsf:9584 case Builtin::BIfabs:9585 case Builtin::BIfabsl:9586 return Builtin::BIcabsf;9587 }9588 }9589 llvm_unreachable("Unable to convert function");9590}9591 9592static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl) {9593 const IdentifierInfo *FnInfo = FDecl->getIdentifier();9594 if (!FnInfo)9595 return 0;9596 9597 switch (FDecl->getBuiltinID()) {9598 default:9599 return 0;9600 case Builtin::BI__builtin_abs:9601 case Builtin::BI__builtin_fabs:9602 case Builtin::BI__builtin_fabsf:9603 case Builtin::BI__builtin_fabsl:9604 case Builtin::BI__builtin_labs:9605 case Builtin::BI__builtin_llabs:9606 case Builtin::BI__builtin_cabs:9607 case Builtin::BI__builtin_cabsf:9608 case Builtin::BI__builtin_cabsl:9609 case Builtin::BIabs:9610 case Builtin::BIlabs:9611 case Builtin::BIllabs:9612 case Builtin::BIfabs:9613 case Builtin::BIfabsf:9614 case Builtin::BIfabsl:9615 case Builtin::BIcabs:9616 case Builtin::BIcabsf:9617 case Builtin::BIcabsl:9618 return FDecl->getBuiltinID();9619 }9620 llvm_unreachable("Unknown Builtin type");9621}9622 9623// If the replacement is valid, emit a note with replacement function.9624// Additionally, suggest including the proper header if not already included.9625static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range,9626 unsigned AbsKind, QualType ArgType) {9627 bool EmitHeaderHint = true;9628 const char *HeaderName = nullptr;9629 std::string FunctionName;9630 if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {9631 FunctionName = "std::abs";9632 if (ArgType->isIntegralOrEnumerationType()) {9633 HeaderName = "cstdlib";9634 } else if (ArgType->isRealFloatingType()) {9635 HeaderName = "cmath";9636 } else {9637 llvm_unreachable("Invalid Type");9638 }9639 9640 // Lookup all std::abs9641 if (NamespaceDecl *Std = S.getStdNamespace()) {9642 LookupResult R(S, &S.Context.Idents.get("abs"), Loc, Sema::LookupAnyName);9643 R.suppressDiagnostics();9644 S.LookupQualifiedName(R, Std);9645 9646 for (const auto *I : R) {9647 const FunctionDecl *FDecl = nullptr;9648 if (const UsingShadowDecl *UsingD = dyn_cast<UsingShadowDecl>(I)) {9649 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());9650 } else {9651 FDecl = dyn_cast<FunctionDecl>(I);9652 }9653 if (!FDecl)9654 continue;9655 9656 // Found std::abs(), check that they are the right ones.9657 if (FDecl->getNumParams() != 1)9658 continue;9659 9660 // Check that the parameter type can handle the argument.9661 QualType ParamType = FDecl->getParamDecl(0)->getType();9662 if (getAbsoluteValueKind(ArgType) == getAbsoluteValueKind(ParamType) &&9663 S.Context.getTypeSize(ArgType) <=9664 S.Context.getTypeSize(ParamType)) {9665 // Found a function, don't need the header hint.9666 EmitHeaderHint = false;9667 break;9668 }9669 }9670 }9671 } else {9672 FunctionName = S.Context.BuiltinInfo.getName(AbsKind);9673 HeaderName = S.Context.BuiltinInfo.getHeaderName(AbsKind);9674 9675 if (HeaderName) {9676 DeclarationName DN(&S.Context.Idents.get(FunctionName));9677 LookupResult R(S, DN, Loc, Sema::LookupAnyName);9678 R.suppressDiagnostics();9679 S.LookupName(R, S.getCurScope());9680 9681 if (R.isSingleResult()) {9682 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());9683 if (FD && FD->getBuiltinID() == AbsKind) {9684 EmitHeaderHint = false;9685 } else {9686 return;9687 }9688 } else if (!R.empty()) {9689 return;9690 }9691 }9692 }9693 9694 S.Diag(Loc, diag::note_replace_abs_function)9695 << FunctionName << FixItHint::CreateReplacement(Range, FunctionName);9696 9697 if (!HeaderName)9698 return;9699 9700 if (!EmitHeaderHint)9701 return;9702 9703 S.Diag(Loc, diag::note_include_header_or_declare) << HeaderName9704 << FunctionName;9705}9706 9707template <std::size_t StrLen>9708static bool IsStdFunction(const FunctionDecl *FDecl,9709 const char (&Str)[StrLen]) {9710 if (!FDecl)9711 return false;9712 if (!FDecl->getIdentifier() || !FDecl->getIdentifier()->isStr(Str))9713 return false;9714 if (!FDecl->isInStdNamespace())9715 return false;9716 9717 return true;9718}9719 9720enum class MathCheck { NaN, Inf };9721static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check) {9722 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {9723 return llvm::is_contained(names, calleeName);9724 };9725 9726 switch (Check) {9727 case MathCheck::NaN:9728 return MatchesAny({"__builtin_nan", "__builtin_nanf", "__builtin_nanl",9729 "__builtin_nanf16", "__builtin_nanf128"});9730 case MathCheck::Inf:9731 return MatchesAny({"__builtin_inf", "__builtin_inff", "__builtin_infl",9732 "__builtin_inff16", "__builtin_inff128"});9733 }9734 llvm_unreachable("unknown MathCheck");9735}9736 9737static bool IsInfinityFunction(const FunctionDecl *FDecl) {9738 if (FDecl->getName() != "infinity")9739 return false;9740 9741 if (const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {9742 const CXXRecordDecl *RDecl = MDecl->getParent();9743 if (RDecl->getName() != "numeric_limits")9744 return false;9745 9746 if (const NamespaceDecl *NSDecl =9747 dyn_cast<NamespaceDecl>(RDecl->getDeclContext()))9748 return NSDecl->isStdNamespace();9749 }9750 9751 return false;9752}9753 9754void Sema::CheckInfNaNFunction(const CallExpr *Call,9755 const FunctionDecl *FDecl) {9756 if (!FDecl->getIdentifier())9757 return;9758 9759 FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts());9760 if (FPO.getNoHonorNaNs() &&9761 (IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") ||9762 IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN))) {9763 Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)9764 << 1 << 0 << Call->getSourceRange();9765 return;9766 }9767 9768 if (FPO.getNoHonorInfs() &&9769 (IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite") ||9770 IsInfinityFunction(FDecl) ||9771 IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf))) {9772 Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)9773 << 0 << 0 << Call->getSourceRange();9774 }9775}9776 9777void Sema::CheckAbsoluteValueFunction(const CallExpr *Call,9778 const FunctionDecl *FDecl) {9779 if (Call->getNumArgs() != 1)9780 return;9781 9782 unsigned AbsKind = getAbsoluteValueFunctionKind(FDecl);9783 bool IsStdAbs = IsStdFunction(FDecl, "abs");9784 if (AbsKind == 0 && !IsStdAbs)9785 return;9786 9787 QualType ArgType = Call->getArg(0)->IgnoreParenImpCasts()->getType();9788 QualType ParamType = Call->getArg(0)->getType();9789 9790 // Unsigned types cannot be negative. Suggest removing the absolute value9791 // function call.9792 if (ArgType->isUnsignedIntegerType()) {9793 std::string FunctionName =9794 IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind);9795 Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;9796 Diag(Call->getExprLoc(), diag::note_remove_abs)9797 << FunctionName9798 << FixItHint::CreateRemoval(Call->getCallee()->getSourceRange());9799 return;9800 }9801 9802 // Taking the absolute value of a pointer is very suspicious, they probably9803 // wanted to index into an array, dereference a pointer, call a function, etc.9804 if (ArgType->isPointerType() || ArgType->canDecayToPointerType()) {9805 unsigned DiagType = 0;9806 if (ArgType->isFunctionType())9807 DiagType = 1;9808 else if (ArgType->isArrayType())9809 DiagType = 2;9810 9811 Diag(Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;9812 return;9813 }9814 9815 // std::abs has overloads which prevent most of the absolute value problems9816 // from occurring.9817 if (IsStdAbs)9818 return;9819 9820 AbsoluteValueKind ArgValueKind = getAbsoluteValueKind(ArgType);9821 AbsoluteValueKind ParamValueKind = getAbsoluteValueKind(ParamType);9822 9823 // The argument and parameter are the same kind. Check if they are the right9824 // size.9825 if (ArgValueKind == ParamValueKind) {9826 if (Context.getTypeSize(ArgType) <= Context.getTypeSize(ParamType))9827 return;9828 9829 unsigned NewAbsKind = getBestAbsFunction(Context, ArgType, AbsKind);9830 Diag(Call->getExprLoc(), diag::warn_abs_too_small)9831 << FDecl << ArgType << ParamType;9832 9833 if (NewAbsKind == 0)9834 return;9835 9836 emitReplacement(*this, Call->getExprLoc(),9837 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);9838 return;9839 }9840 9841 // ArgValueKind != ParamValueKind9842 // The wrong type of absolute value function was used. Attempt to find the9843 // proper one.9844 unsigned NewAbsKind = changeAbsFunction(AbsKind, ArgValueKind);9845 NewAbsKind = getBestAbsFunction(Context, ArgType, NewAbsKind);9846 if (NewAbsKind == 0)9847 return;9848 9849 Diag(Call->getExprLoc(), diag::warn_wrong_absolute_value_type)9850 << FDecl << ParamValueKind << ArgValueKind;9851 9852 emitReplacement(*this, Call->getExprLoc(),9853 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);9854}9855 9856//===--- CHECK: Warn on use of std::max and unsigned zero. r---------------===//9857void Sema::CheckMaxUnsignedZero(const CallExpr *Call,9858 const FunctionDecl *FDecl) {9859 if (!Call || !FDecl) return;9860 9861 // Ignore template specializations and macros.9862 if (inTemplateInstantiation()) return;9863 if (Call->getExprLoc().isMacroID()) return;9864 9865 // Only care about the one template argument, two function parameter std::max9866 if (Call->getNumArgs() != 2) return;9867 if (!IsStdFunction(FDecl, "max")) return;9868 const auto * ArgList = FDecl->getTemplateSpecializationArgs();9869 if (!ArgList) return;9870 if (ArgList->size() != 1) return;9871 9872 // Check that template type argument is unsigned integer.9873 const auto& TA = ArgList->get(0);9874 if (TA.getKind() != TemplateArgument::Type) return;9875 QualType ArgType = TA.getAsType();9876 if (!ArgType->isUnsignedIntegerType()) return;9877 9878 // See if either argument is a literal zero.9879 auto IsLiteralZeroArg = [](const Expr* E) -> bool {9880 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);9881 if (!MTE) return false;9882 const auto *Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());9883 if (!Num) return false;9884 if (Num->getValue() != 0) return false;9885 return true;9886 };9887 9888 const Expr *FirstArg = Call->getArg(0);9889 const Expr *SecondArg = Call->getArg(1);9890 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);9891 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);9892 9893 // Only warn when exactly one argument is zero.9894 if (IsFirstArgZero == IsSecondArgZero) return;9895 9896 SourceRange FirstRange = FirstArg->getSourceRange();9897 SourceRange SecondRange = SecondArg->getSourceRange();9898 9899 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;9900 9901 Diag(Call->getExprLoc(), diag::warn_max_unsigned_zero)9902 << IsFirstArgZero << Call->getCallee()->getSourceRange() << ZeroRange;9903 9904 // Deduce what parts to remove so that "std::max(0u, foo)" becomes "(foo)".9905 SourceRange RemovalRange;9906 if (IsFirstArgZero) {9907 RemovalRange = SourceRange(FirstRange.getBegin(),9908 SecondRange.getBegin().getLocWithOffset(-1));9909 } else {9910 RemovalRange = SourceRange(getLocForEndOfToken(FirstRange.getEnd()),9911 SecondRange.getEnd());9912 }9913 9914 Diag(Call->getExprLoc(), diag::note_remove_max_call)9915 << FixItHint::CreateRemoval(Call->getCallee()->getSourceRange())9916 << FixItHint::CreateRemoval(RemovalRange);9917}9918 9919//===--- CHECK: Standard memory functions ---------------------------------===//9920 9921/// Takes the expression passed to the size_t parameter of functions9922/// such as memcmp, strncat, etc and warns if it's a comparison.9923///9924/// This is to catch typos like `if (memcmp(&a, &b, sizeof(a) > 0))`.9925static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E,9926 const IdentifierInfo *FnName,9927 SourceLocation FnLoc,9928 SourceLocation RParenLoc) {9929 const auto *Size = dyn_cast<BinaryOperator>(E);9930 if (!Size)9931 return false;9932 9933 // if E is binop and op is <=>, >, <, >=, <=, ==, &&, ||:9934 if (!Size->isComparisonOp() && !Size->isLogicalOp())9935 return false;9936 9937 SourceRange SizeRange = Size->getSourceRange();9938 S.Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)9939 << SizeRange << FnName;9940 S.Diag(FnLoc, diag::note_memsize_comparison_paren)9941 << FnName9942 << FixItHint::CreateInsertion(9943 S.getLocForEndOfToken(Size->getLHS()->getEndLoc()), ")")9944 << FixItHint::CreateRemoval(RParenLoc);9945 S.Diag(SizeRange.getBegin(), diag::note_memsize_comparison_cast_silence)9946 << FixItHint::CreateInsertion(SizeRange.getBegin(), "(size_t)(")9947 << FixItHint::CreateInsertion(S.getLocForEndOfToken(SizeRange.getEnd()),9948 ")");9949 9950 return true;9951}9952 9953/// Determine whether the given type is or contains a dynamic class type9954/// (e.g., whether it has a vtable).9955static const CXXRecordDecl *getContainedDynamicClass(QualType T,9956 bool &IsContained) {9957 // Look through array types while ignoring qualifiers.9958 const Type *Ty = T->getBaseElementTypeUnsafe();9959 IsContained = false;9960 9961 const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();9962 RD = RD ? RD->getDefinition() : nullptr;9963 if (!RD || RD->isInvalidDecl())9964 return nullptr;9965 9966 if (RD->isDynamicClass())9967 return RD;9968 9969 // Check all the fields. If any bases were dynamic, the class is dynamic.9970 // It's impossible for a class to transitively contain itself by value, so9971 // infinite recursion is impossible.9972 for (auto *FD : RD->fields()) {9973 bool SubContained;9974 if (const CXXRecordDecl *ContainedRD =9975 getContainedDynamicClass(FD->getType(), SubContained)) {9976 IsContained = true;9977 return ContainedRD;9978 }9979 }9980 9981 return nullptr;9982}9983 9984static const UnaryExprOrTypeTraitExpr *getAsSizeOfExpr(const Expr *E) {9985 if (const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))9986 if (Unary->getKind() == UETT_SizeOf)9987 return Unary;9988 return nullptr;9989}9990 9991/// If E is a sizeof expression, returns its argument expression,9992/// otherwise returns NULL.9993static const Expr *getSizeOfExprArg(const Expr *E) {9994 if (const UnaryExprOrTypeTraitExpr *SizeOf = getAsSizeOfExpr(E))9995 if (!SizeOf->isArgumentType())9996 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();9997 return nullptr;9998}9999 10000/// If E is a sizeof expression, returns its argument type.10001static QualType getSizeOfArgType(const Expr *E) {10002 if (const UnaryExprOrTypeTraitExpr *SizeOf = getAsSizeOfExpr(E))10003 return SizeOf->getTypeOfArgument();10004 return QualType();10005}10006 10007namespace {10008 10009struct SearchNonTrivialToInitializeField10010 : DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField> {10011 using Super =10012 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;10013 10014 SearchNonTrivialToInitializeField(const Expr *E, Sema &S) : E(E), S(S) {}10015 10016 void visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType FT,10017 SourceLocation SL) {10018 if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {10019 asDerived().visitArray(PDIK, AT, SL);10020 return;10021 }10022 10023 Super::visitWithKind(PDIK, FT, SL);10024 }10025 10026 void visitARCStrong(QualType FT, SourceLocation SL) {10027 S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 1);10028 }10029 void visitARCWeak(QualType FT, SourceLocation SL) {10030 S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 1);10031 }10032 void visitStruct(QualType FT, SourceLocation SL) {10033 for (const FieldDecl *FD : FT->castAsRecordDecl()->fields())10034 visit(FD->getType(), FD->getLocation());10035 }10036 void visitArray(QualType::PrimitiveDefaultInitializeKind PDIK,10037 const ArrayType *AT, SourceLocation SL) {10038 visit(getContext().getBaseElementType(AT), SL);10039 }10040 void visitTrivial(QualType FT, SourceLocation SL) {}10041 10042 static void diag(QualType RT, const Expr *E, Sema &S) {10043 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());10044 }10045 10046 ASTContext &getContext() { return S.getASTContext(); }10047 10048 const Expr *E;10049 Sema &S;10050};10051 10052struct SearchNonTrivialToCopyField10053 : CopiedTypeVisitor<SearchNonTrivialToCopyField, false> {10054 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;10055 10056 SearchNonTrivialToCopyField(const Expr *E, Sema &S) : E(E), S(S) {}10057 10058 void visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,10059 SourceLocation SL) {10060 if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {10061 asDerived().visitArray(PCK, AT, SL);10062 return;10063 }10064 10065 Super::visitWithKind(PCK, FT, SL);10066 }10067 10068 void visitARCStrong(QualType FT, SourceLocation SL) {10069 S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0);10070 }10071 void visitARCWeak(QualType FT, SourceLocation SL) {10072 S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0);10073 }10074 void visitPtrAuth(QualType FT, SourceLocation SL) {10075 S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0);10076 }10077 void visitStruct(QualType FT, SourceLocation SL) {10078 for (const FieldDecl *FD : FT->castAsRecordDecl()->fields())10079 visit(FD->getType(), FD->getLocation());10080 }10081 void visitArray(QualType::PrimitiveCopyKind PCK, const ArrayType *AT,10082 SourceLocation SL) {10083 visit(getContext().getBaseElementType(AT), SL);10084 }10085 void preVisit(QualType::PrimitiveCopyKind PCK, QualType FT,10086 SourceLocation SL) {}10087 void visitTrivial(QualType FT, SourceLocation SL) {}10088 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}10089 10090 static void diag(QualType RT, const Expr *E, Sema &S) {10091 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());10092 }10093 10094 ASTContext &getContext() { return S.getASTContext(); }10095 10096 const Expr *E;10097 Sema &S;10098};10099 10100}10101 10102/// Detect if \c SizeofExpr is likely to calculate the sizeof an object.10103static bool doesExprLikelyComputeSize(const Expr *SizeofExpr) {10104 SizeofExpr = SizeofExpr->IgnoreParenImpCasts();10105 10106 if (const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {10107 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)10108 return false;10109 10110 return doesExprLikelyComputeSize(BO->getLHS()) ||10111 doesExprLikelyComputeSize(BO->getRHS());10112 }10113 10114 return getAsSizeOfExpr(SizeofExpr) != nullptr;10115}10116 10117/// Check if the ArgLoc originated from a macro passed to the call at CallLoc.10118///10119/// \code10120/// #define MACRO 010121/// foo(MACRO);10122/// foo(0);10123/// \endcode10124///10125/// This should return true for the first call to foo, but not for the second10126/// (regardless of whether foo is a macro or function).10127static bool isArgumentExpandedFromMacro(SourceManager &SM,10128 SourceLocation CallLoc,10129 SourceLocation ArgLoc) {10130 if (!CallLoc.isMacroID())10131 return SM.getFileID(CallLoc) != SM.getFileID(ArgLoc);10132 10133 return SM.getFileID(SM.getImmediateMacroCallerLoc(CallLoc)) !=10134 SM.getFileID(SM.getImmediateMacroCallerLoc(ArgLoc));10135}10136 10137/// Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the10138/// last two arguments transposed.10139static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call) {10140 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)10141 return;10142 10143 const Expr *SizeArg =10144 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();10145 10146 auto isLiteralZero = [](const Expr *E) {10147 return (isa<IntegerLiteral>(E) &&10148 cast<IntegerLiteral>(E)->getValue() == 0) ||10149 (isa<CharacterLiteral>(E) &&10150 cast<CharacterLiteral>(E)->getValue() == 0);10151 };10152 10153 // If we're memsetting or bzeroing 0 bytes, then this is likely an error.10154 SourceLocation CallLoc = Call->getRParenLoc();10155 SourceManager &SM = S.getSourceManager();10156 if (isLiteralZero(SizeArg) &&10157 !isArgumentExpandedFromMacro(SM, CallLoc, SizeArg->getExprLoc())) {10158 10159 SourceLocation DiagLoc = SizeArg->getExprLoc();10160 10161 // Some platforms #define bzero to __builtin_memset. See if this is the10162 // case, and if so, emit a better diagnostic.10163 if (BId == Builtin::BIbzero ||10164 (CallLoc.isMacroID() && Lexer::getImmediateMacroName(10165 CallLoc, SM, S.getLangOpts()) == "bzero")) {10166 S.Diag(DiagLoc, diag::warn_suspicious_bzero_size);10167 S.Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);10168 } else if (!isLiteralZero(Call->getArg(1)->IgnoreImpCasts())) {10169 S.Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;10170 S.Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;10171 }10172 return;10173 }10174 10175 // If the second argument to a memset is a sizeof expression and the third10176 // isn't, this is also likely an error. This should catch10177 // 'memset(buf, sizeof(buf), 0xff)'.10178 if (BId == Builtin::BImemset &&10179 doesExprLikelyComputeSize(Call->getArg(1)) &&10180 !doesExprLikelyComputeSize(Call->getArg(2))) {10181 SourceLocation DiagLoc = Call->getArg(1)->getExprLoc();10182 S.Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;10183 S.Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;10184 return;10185 }10186}10187 10188void Sema::CheckMemaccessArguments(const CallExpr *Call,10189 unsigned BId,10190 IdentifierInfo *FnName) {10191 assert(BId != 0);10192 10193 // It is possible to have a non-standard definition of memset. Validate10194 // we have enough arguments, and if not, abort further checking.10195 unsigned ExpectedNumArgs =10196 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);10197 if (Call->getNumArgs() < ExpectedNumArgs)10198 return;10199 10200 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||10201 BId == Builtin::BIstrndup ? 1 : 2);10202 unsigned LenArg =10203 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);10204 const Expr *LenExpr = Call->getArg(LenArg)->IgnoreParenImpCasts();10205 10206 if (CheckMemorySizeofForComparison(*this, LenExpr, FnName,10207 Call->getBeginLoc(), Call->getRParenLoc()))10208 return;10209 10210 // Catch cases like 'memset(buf, sizeof(buf), 0)'.10211 CheckMemaccessSize(*this, BId, Call);10212 10213 // We have special checking when the length is a sizeof expression.10214 QualType SizeOfArgTy = getSizeOfArgType(LenExpr);10215 const Expr *SizeOfArg = getSizeOfExprArg(LenExpr);10216 llvm::FoldingSetNodeID SizeOfArgID;10217 10218 // Although widely used, 'bzero' is not a standard function. Be more strict10219 // with the argument types before allowing diagnostics and only allow the10220 // form bzero(ptr, sizeof(...)).10221 QualType FirstArgTy = Call->getArg(0)->IgnoreParenImpCasts()->getType();10222 if (BId == Builtin::BIbzero && !FirstArgTy->getAs<PointerType>())10223 return;10224 10225 for (unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {10226 const Expr *Dest = Call->getArg(ArgIdx)->IgnoreParenImpCasts();10227 SourceRange ArgRange = Call->getArg(ArgIdx)->getSourceRange();10228 10229 QualType DestTy = Dest->getType();10230 QualType PointeeTy;10231 if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) {10232 PointeeTy = DestPtrTy->getPointeeType();10233 10234 // Never warn about void type pointers. This can be used to suppress10235 // false positives.10236 if (PointeeTy->isVoidType())10237 continue;10238 10239 // Catch "memset(p, 0, sizeof(p))" -- needs to be sizeof(*p). Do this by10240 // actually comparing the expressions for equality. Because computing the10241 // expression IDs can be expensive, we only do this if the diagnostic is10242 // enabled.10243 if (SizeOfArg &&10244 !Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,10245 SizeOfArg->getExprLoc())) {10246 // We only compute IDs for expressions if the warning is enabled, and10247 // cache the sizeof arg's ID.10248 if (SizeOfArgID == llvm::FoldingSetNodeID())10249 SizeOfArg->Profile(SizeOfArgID, Context, true);10250 llvm::FoldingSetNodeID DestID;10251 Dest->Profile(DestID, Context, true);10252 if (DestID == SizeOfArgID) {10253 // TODO: For strncpy() and friends, this could suggest sizeof(dst)10254 // over sizeof(src) as well.10255 unsigned ActionIdx = 0; // Default is to suggest dereferencing.10256 StringRef ReadableName = FnName->getName();10257 10258 if (const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))10259 if (UnaryOp->getOpcode() == UO_AddrOf)10260 ActionIdx = 1; // If its an address-of operator, just remove it.10261 if (!PointeeTy->isIncompleteType() &&10262 (Context.getTypeSize(PointeeTy) == Context.getCharWidth()))10263 ActionIdx = 2; // If the pointee's size is sizeof(char),10264 // suggest an explicit length.10265 10266 // If the function is defined as a builtin macro, do not show macro10267 // expansion.10268 SourceLocation SL = SizeOfArg->getExprLoc();10269 SourceRange DSR = Dest->getSourceRange();10270 SourceRange SSR = SizeOfArg->getSourceRange();10271 SourceManager &SM = getSourceManager();10272 10273 if (SM.isMacroArgExpansion(SL)) {10274 ReadableName = Lexer::getImmediateMacroName(SL, SM, LangOpts);10275 SL = SM.getSpellingLoc(SL);10276 DSR = SourceRange(SM.getSpellingLoc(DSR.getBegin()),10277 SM.getSpellingLoc(DSR.getEnd()));10278 SSR = SourceRange(SM.getSpellingLoc(SSR.getBegin()),10279 SM.getSpellingLoc(SSR.getEnd()));10280 }10281 10282 DiagRuntimeBehavior(SL, SizeOfArg,10283 PDiag(diag::warn_sizeof_pointer_expr_memaccess)10284 << ReadableName10285 << PointeeTy10286 << DestTy10287 << DSR10288 << SSR);10289 DiagRuntimeBehavior(SL, SizeOfArg,10290 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)10291 << ActionIdx10292 << SSR);10293 10294 break;10295 }10296 }10297 10298 // Also check for cases where the sizeof argument is the exact same10299 // type as the memory argument, and where it points to a user-defined10300 // record type.10301 if (SizeOfArgTy != QualType()) {10302 if (PointeeTy->isRecordType() &&10303 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {10304 DiagRuntimeBehavior(LenExpr->getExprLoc(), Dest,10305 PDiag(diag::warn_sizeof_pointer_type_memaccess)10306 << FnName << SizeOfArgTy << ArgIdx10307 << PointeeTy << Dest->getSourceRange()10308 << LenExpr->getSourceRange());10309 break;10310 }10311 }10312 } else if (DestTy->isArrayType()) {10313 PointeeTy = DestTy;10314 }10315 10316 if (PointeeTy == QualType())10317 continue;10318 10319 // Always complain about dynamic classes.10320 bool IsContained;10321 if (const CXXRecordDecl *ContainedRD =10322 getContainedDynamicClass(PointeeTy, IsContained)) {10323 10324 unsigned OperationType = 0;10325 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;10326 // "overwritten" if we're warning about the destination for any call10327 // but memcmp; otherwise a verb appropriate to the call.10328 if (ArgIdx != 0 || IsCmp) {10329 if (BId == Builtin::BImemcpy)10330 OperationType = 1;10331 else if(BId == Builtin::BImemmove)10332 OperationType = 2;10333 else if (IsCmp)10334 OperationType = 3;10335 }10336 10337 DiagRuntimeBehavior(Dest->getExprLoc(), Dest,10338 PDiag(diag::warn_dyn_class_memaccess)10339 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName10340 << IsContained << ContainedRD << OperationType10341 << Call->getCallee()->getSourceRange());10342 } else if (PointeeTy.hasNonTrivialObjCLifetime() &&10343 BId != Builtin::BImemset)10344 DiagRuntimeBehavior(10345 Dest->getExprLoc(), Dest,10346 PDiag(diag::warn_arc_object_memaccess)10347 << ArgIdx << FnName << PointeeTy10348 << Call->getCallee()->getSourceRange());10349 else if (const auto *RD = PointeeTy->getAsRecordDecl()) {10350 10351 // FIXME: Do not consider incomplete types even though they may be10352 // completed later. GCC does not diagnose such code, but we may want to10353 // consider diagnosing it in the future, perhaps under a different, but10354 // related, diagnostic group.10355 bool NonTriviallyCopyableCXXRecord =10356 getLangOpts().CPlusPlus && RD->isCompleteDefinition() &&10357 !PointeeTy.isTriviallyCopyableType(Context);10358 10359 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&10360 RD->isNonTrivialToPrimitiveDefaultInitialize()) {10361 DiagRuntimeBehavior(Dest->getExprLoc(), Dest,10362 PDiag(diag::warn_cstruct_memaccess)10363 << ArgIdx << FnName << PointeeTy << 0);10364 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *this);10365 } else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&10366 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {10367 // FIXME: Limiting this warning to dest argument until we decide10368 // whether it's valid for source argument too.10369 DiagRuntimeBehavior(Dest->getExprLoc(), Dest,10370 PDiag(diag::warn_cxxstruct_memaccess)10371 << FnName << PointeeTy);10372 } else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&10373 RD->isNonTrivialToPrimitiveCopy()) {10374 DiagRuntimeBehavior(Dest->getExprLoc(), Dest,10375 PDiag(diag::warn_cstruct_memaccess)10376 << ArgIdx << FnName << PointeeTy << 1);10377 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *this);10378 } else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&10379 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {10380 // FIXME: Limiting this warning to dest argument until we decide10381 // whether it's valid for source argument too.10382 DiagRuntimeBehavior(Dest->getExprLoc(), Dest,10383 PDiag(diag::warn_cxxstruct_memaccess)10384 << FnName << PointeeTy);10385 } else {10386 continue;10387 }10388 } else10389 continue;10390 10391 DiagRuntimeBehavior(10392 Dest->getExprLoc(), Dest,10393 PDiag(diag::note_bad_memaccess_silence)10394 << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)"));10395 break;10396 }10397}10398 10399// A little helper routine: ignore addition and subtraction of integer literals.10400// This intentionally does not ignore all integer constant expressions because10401// we don't want to remove sizeof().10402static const Expr *ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx) {10403 Ex = Ex->IgnoreParenCasts();10404 10405 while (true) {10406 const BinaryOperator * BO = dyn_cast<BinaryOperator>(Ex);10407 if (!BO || !BO->isAdditiveOp())10408 break;10409 10410 const Expr *RHS = BO->getRHS()->IgnoreParenCasts();10411 const Expr *LHS = BO->getLHS()->IgnoreParenCasts();10412 10413 if (isa<IntegerLiteral>(RHS))10414 Ex = LHS;10415 else if (isa<IntegerLiteral>(LHS))10416 Ex = RHS;10417 else10418 break;10419 }10420 10421 return Ex;10422}10423 10424static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty,10425 ASTContext &Context) {10426 // Only handle constant-sized or VLAs, but not flexible members.10427 if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(Ty)) {10428 // Only issue the FIXIT for arrays of size > 1.10429 if (CAT->getZExtSize() <= 1)10430 return false;10431 } else if (!Ty->isVariableArrayType()) {10432 return false;10433 }10434 return true;10435}10436 10437void Sema::CheckStrlcpycatArguments(const CallExpr *Call,10438 IdentifierInfo *FnName) {10439 10440 // Don't crash if the user has the wrong number of arguments10441 unsigned NumArgs = Call->getNumArgs();10442 if ((NumArgs != 3) && (NumArgs != 4))10443 return;10444 10445 const Expr *SrcArg = ignoreLiteralAdditions(Call->getArg(1), Context);10446 const Expr *SizeArg = ignoreLiteralAdditions(Call->getArg(2), Context);10447 const Expr *CompareWithSrc = nullptr;10448 10449 if (CheckMemorySizeofForComparison(*this, SizeArg, FnName,10450 Call->getBeginLoc(), Call->getRParenLoc()))10451 return;10452 10453 // Look for 'strlcpy(dst, x, sizeof(x))'10454 if (const Expr *Ex = getSizeOfExprArg(SizeArg))10455 CompareWithSrc = Ex;10456 else {10457 // Look for 'strlcpy(dst, x, strlen(x))'10458 if (const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {10459 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&10460 SizeCall->getNumArgs() == 1)10461 CompareWithSrc = ignoreLiteralAdditions(SizeCall->getArg(0), Context);10462 }10463 }10464 10465 if (!CompareWithSrc)10466 return;10467 10468 // Determine if the argument to sizeof/strlen is equal to the source10469 // argument. In principle there's all kinds of things you could do10470 // here, for instance creating an == expression and evaluating it with10471 // EvaluateAsBooleanCondition, but this uses a more direct technique:10472 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);10473 if (!SrcArgDRE)10474 return;10475 10476 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);10477 if (!CompareWithSrcDRE ||10478 SrcArgDRE->getDecl() != CompareWithSrcDRE->getDecl())10479 return;10480 10481 const Expr *OriginalSizeArg = Call->getArg(2);10482 Diag(CompareWithSrcDRE->getBeginLoc(), diag::warn_strlcpycat_wrong_size)10483 << OriginalSizeArg->getSourceRange() << FnName;10484 10485 // Output a FIXIT hint if the destination is an array (rather than a10486 // pointer to an array). This could be enhanced to handle some10487 // pointers if we know the actual size, like if DstArg is 'array+2'10488 // we could say 'sizeof(array)-2'.10489 const Expr *DstArg = Call->getArg(0)->IgnoreParenImpCasts();10490 if (!isConstantSizeArrayWithMoreThanOneElement(DstArg->getType(), Context))10491 return;10492 10493 SmallString<128> sizeString;10494 llvm::raw_svector_ostream OS(sizeString);10495 OS << "sizeof(";10496 DstArg->printPretty(OS, nullptr, getPrintingPolicy());10497 OS << ")";10498 10499 Diag(OriginalSizeArg->getBeginLoc(), diag::note_strlcpycat_wrong_size)10500 << FixItHint::CreateReplacement(OriginalSizeArg->getSourceRange(),10501 OS.str());10502}10503 10504/// Check if two expressions refer to the same declaration.10505static bool referToTheSameDecl(const Expr *E1, const Expr *E2) {10506 if (const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))10507 if (const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))10508 return D1->getDecl() == D2->getDecl();10509 return false;10510}10511 10512static const Expr *getStrlenExprArg(const Expr *E) {10513 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {10514 const FunctionDecl *FD = CE->getDirectCallee();10515 if (!FD || FD->getMemoryFunctionKind() != Builtin::BIstrlen)10516 return nullptr;10517 return CE->getArg(0)->IgnoreParenCasts();10518 }10519 return nullptr;10520}10521 10522void Sema::CheckStrncatArguments(const CallExpr *CE,10523 const IdentifierInfo *FnName) {10524 // Don't crash if the user has the wrong number of arguments.10525 if (CE->getNumArgs() < 3)10526 return;10527 const Expr *DstArg = CE->getArg(0)->IgnoreParenCasts();10528 const Expr *SrcArg = CE->getArg(1)->IgnoreParenCasts();10529 const Expr *LenArg = CE->getArg(2)->IgnoreParenCasts();10530 10531 if (CheckMemorySizeofForComparison(*this, LenArg, FnName, CE->getBeginLoc(),10532 CE->getRParenLoc()))10533 return;10534 10535 // Identify common expressions, which are wrongly used as the size argument10536 // to strncat and may lead to buffer overflows.10537 unsigned PatternType = 0;10538 if (const Expr *SizeOfArg = getSizeOfExprArg(LenArg)) {10539 // - sizeof(dst)10540 if (referToTheSameDecl(SizeOfArg, DstArg))10541 PatternType = 1;10542 // - sizeof(src)10543 else if (referToTheSameDecl(SizeOfArg, SrcArg))10544 PatternType = 2;10545 } else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {10546 if (BE->getOpcode() == BO_Sub) {10547 const Expr *L = BE->getLHS()->IgnoreParenCasts();10548 const Expr *R = BE->getRHS()->IgnoreParenCasts();10549 // - sizeof(dst) - strlen(dst)10550 if (referToTheSameDecl(DstArg, getSizeOfExprArg(L)) &&10551 referToTheSameDecl(DstArg, getStrlenExprArg(R)))10552 PatternType = 1;10553 // - sizeof(src) - (anything)10554 else if (referToTheSameDecl(SrcArg, getSizeOfExprArg(L)))10555 PatternType = 2;10556 }10557 }10558 10559 if (PatternType == 0)10560 return;10561 10562 // Generate the diagnostic.10563 SourceLocation SL = LenArg->getBeginLoc();10564 SourceRange SR = LenArg->getSourceRange();10565 SourceManager &SM = getSourceManager();10566 10567 // If the function is defined as a builtin macro, do not show macro expansion.10568 if (SM.isMacroArgExpansion(SL)) {10569 SL = SM.getSpellingLoc(SL);10570 SR = SourceRange(SM.getSpellingLoc(SR.getBegin()),10571 SM.getSpellingLoc(SR.getEnd()));10572 }10573 10574 // Check if the destination is an array (rather than a pointer to an array).10575 QualType DstTy = DstArg->getType();10576 bool isKnownSizeArray = isConstantSizeArrayWithMoreThanOneElement(DstTy,10577 Context);10578 if (!isKnownSizeArray) {10579 if (PatternType == 1)10580 Diag(SL, diag::warn_strncat_wrong_size) << SR;10581 else10582 Diag(SL, diag::warn_strncat_src_size) << SR;10583 return;10584 }10585 10586 if (PatternType == 1)10587 Diag(SL, diag::warn_strncat_large_size) << SR;10588 else10589 Diag(SL, diag::warn_strncat_src_size) << SR;10590 10591 SmallString<128> sizeString;10592 llvm::raw_svector_ostream OS(sizeString);10593 OS << "sizeof(";10594 DstArg->printPretty(OS, nullptr, getPrintingPolicy());10595 OS << ") - ";10596 OS << "strlen(";10597 DstArg->printPretty(OS, nullptr, getPrintingPolicy());10598 OS << ") - 1";10599 10600 Diag(SL, diag::note_strncat_wrong_size)10601 << FixItHint::CreateReplacement(SR, OS.str());10602}10603 10604namespace {10605void CheckFreeArgumentsOnLvalue(Sema &S, const std::string &CalleeName,10606 const UnaryOperator *UnaryExpr, const Decl *D) {10607 if (isa<FieldDecl, FunctionDecl, VarDecl>(D)) {10608 S.Diag(UnaryExpr->getBeginLoc(), diag::warn_free_nonheap_object)10609 << CalleeName << 0 /*object: */ << cast<NamedDecl>(D);10610 return;10611 }10612}10613 10614void CheckFreeArgumentsAddressof(Sema &S, const std::string &CalleeName,10615 const UnaryOperator *UnaryExpr) {10616 if (const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->getSubExpr())) {10617 const Decl *D = Lvalue->getDecl();10618 if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) {10619 if (!DD->getType()->isReferenceType())10620 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);10621 }10622 }10623 10624 if (const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->getSubExpr()))10625 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,10626 Lvalue->getMemberDecl());10627}10628 10629void CheckFreeArgumentsPlus(Sema &S, const std::string &CalleeName,10630 const UnaryOperator *UnaryExpr) {10631 const auto *Lambda = dyn_cast<LambdaExpr>(10632 UnaryExpr->getSubExpr()->IgnoreImplicitAsWritten()->IgnoreParens());10633 if (!Lambda)10634 return;10635 10636 S.Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)10637 << CalleeName << 2 /*object: lambda expression*/;10638}10639 10640void CheckFreeArgumentsStackArray(Sema &S, const std::string &CalleeName,10641 const DeclRefExpr *Lvalue) {10642 const auto *Var = dyn_cast<VarDecl>(Lvalue->getDecl());10643 if (Var == nullptr)10644 return;10645 10646 S.Diag(Lvalue->getBeginLoc(), diag::warn_free_nonheap_object)10647 << CalleeName << 0 /*object: */ << Var;10648}10649 10650void CheckFreeArgumentsCast(Sema &S, const std::string &CalleeName,10651 const CastExpr *Cast) {10652 SmallString<128> SizeString;10653 llvm::raw_svector_ostream OS(SizeString);10654 10655 clang::CastKind Kind = Cast->getCastKind();10656 if (Kind == clang::CK_BitCast &&10657 !Cast->getSubExpr()->getType()->isFunctionPointerType())10658 return;10659 if (Kind == clang::CK_IntegralToPointer &&10660 !isa<IntegerLiteral>(10661 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))10662 return;10663 10664 switch (Cast->getCastKind()) {10665 case clang::CK_BitCast:10666 case clang::CK_IntegralToPointer:10667 case clang::CK_FunctionToPointerDecay:10668 OS << '\'';10669 Cast->printPretty(OS, nullptr, S.getPrintingPolicy());10670 OS << '\'';10671 break;10672 default:10673 return;10674 }10675 10676 S.Diag(Cast->getBeginLoc(), diag::warn_free_nonheap_object)10677 << CalleeName << 0 /*object: */ << OS.str();10678}10679} // namespace10680 10681void Sema::CheckFreeArguments(const CallExpr *E) {10682 const std::string CalleeName =10683 cast<FunctionDecl>(E->getCalleeDecl())->getQualifiedNameAsString();10684 10685 { // Prefer something that doesn't involve a cast to make things simpler.10686 const Expr *Arg = E->getArg(0)->IgnoreParenCasts();10687 if (const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))10688 switch (UnaryExpr->getOpcode()) {10689 case UnaryOperator::Opcode::UO_AddrOf:10690 return CheckFreeArgumentsAddressof(*this, CalleeName, UnaryExpr);10691 case UnaryOperator::Opcode::UO_Plus:10692 return CheckFreeArgumentsPlus(*this, CalleeName, UnaryExpr);10693 default:10694 break;10695 }10696 10697 if (const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))10698 if (Lvalue->getType()->isArrayType())10699 return CheckFreeArgumentsStackArray(*this, CalleeName, Lvalue);10700 10701 if (const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {10702 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)10703 << CalleeName << 0 /*object: */ << Label->getLabel()->getIdentifier();10704 return;10705 }10706 10707 if (isa<BlockExpr>(Arg)) {10708 Diag(Arg->getBeginLoc(), diag::warn_free_nonheap_object)10709 << CalleeName << 1 /*object: block*/;10710 return;10711 }10712 }10713 // Maybe the cast was important, check after the other cases.10714 if (const auto *Cast = dyn_cast<CastExpr>(E->getArg(0)))10715 return CheckFreeArgumentsCast(*this, CalleeName, Cast);10716}10717 10718void10719Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType,10720 SourceLocation ReturnLoc,10721 bool isObjCMethod,10722 const AttrVec *Attrs,10723 const FunctionDecl *FD) {10724 // Check if the return value is null but should not be.10725 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||10726 (!isObjCMethod && isNonNullType(lhsType))) &&10727 CheckNonNullExpr(*this, RetValExp))10728 Diag(ReturnLoc, diag::warn_null_ret)10729 << (isObjCMethod ? 1 : 0) << RetValExp->getSourceRange();10730 10731 // C++11 [basic.stc.dynamic.allocation]p4:10732 // If an allocation function declared with a non-throwing10733 // exception-specification fails to allocate storage, it shall return10734 // a null pointer. Any other allocation function that fails to allocate10735 // storage shall indicate failure only by throwing an exception [...]10736 if (FD) {10737 OverloadedOperatorKind Op = FD->getOverloadedOperator();10738 if (Op == OO_New || Op == OO_Array_New) {10739 const FunctionProtoType *Proto10740 = FD->getType()->castAs<FunctionProtoType>();10741 if (!Proto->isNothrow(/*ResultIfDependent*/true) &&10742 CheckNonNullExpr(*this, RetValExp))10743 Diag(ReturnLoc, diag::warn_operator_new_returns_null)10744 << FD << getLangOpts().CPlusPlus11;10745 }10746 }10747 10748 if (RetValExp && RetValExp->getType()->isWebAssemblyTableType()) {10749 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;10750 }10751 10752 // PPC MMA non-pointer types are not allowed as return type. Checking the type10753 // here prevent the user from using a PPC MMA type as trailing return type.10754 if (Context.getTargetInfo().getTriple().isPPC64())10755 PPC().CheckPPCMMAType(RetValExp->getType(), ReturnLoc);10756}10757 10758void Sema::CheckFloatComparison(SourceLocation Loc, const Expr *LHS,10759 const Expr *RHS, BinaryOperatorKind Opcode) {10760 if (!BinaryOperator::isEqualityOp(Opcode))10761 return;10762 10763 // Match and capture subexpressions such as "(float) X == 0.1".10764 const FloatingLiteral *FPLiteral;10765 const CastExpr *FPCast;10766 auto getCastAndLiteral = [&FPLiteral, &FPCast](const Expr *L, const Expr *R) {10767 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());10768 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());10769 return FPLiteral && FPCast;10770 };10771 10772 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {10773 auto *SourceTy = FPCast->getSubExpr()->getType()->getAs<BuiltinType>();10774 auto *TargetTy = FPLiteral->getType()->getAs<BuiltinType>();10775 if (SourceTy && TargetTy && SourceTy->isFloatingPoint() &&10776 TargetTy->isFloatingPoint()) {10777 bool Lossy;10778 llvm::APFloat TargetC = FPLiteral->getValue();10779 TargetC.convert(Context.getFloatTypeSemantics(QualType(SourceTy, 0)),10780 llvm::APFloat::rmNearestTiesToEven, &Lossy);10781 if (Lossy) {10782 // If the literal cannot be represented in the source type, then a10783 // check for == is always false and check for != is always true.10784 Diag(Loc, diag::warn_float_compare_literal)10785 << (Opcode == BO_EQ) << QualType(SourceTy, 0)10786 << LHS->getSourceRange() << RHS->getSourceRange();10787 return;10788 }10789 }10790 }10791 10792 // Match a more general floating-point equality comparison (-Wfloat-equal).10793 const Expr *LeftExprSansParen = LHS->IgnoreParenImpCasts();10794 const Expr *RightExprSansParen = RHS->IgnoreParenImpCasts();10795 10796 // Special case: check for x == x (which is OK).10797 // Do not emit warnings for such cases.10798 if (const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))10799 if (const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))10800 if (DRL->getDecl() == DRR->getDecl())10801 return;10802 10803 // Special case: check for comparisons against literals that can be exactly10804 // represented by APFloat. In such cases, do not emit a warning. This10805 // is a heuristic: often comparison against such literals are used to10806 // detect if a value in a variable has not changed. This clearly can10807 // lead to false negatives.10808 if (const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {10809 if (FLL->isExact())10810 return;10811 } else if (const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))10812 if (FLR->isExact())10813 return;10814 10815 // Check for comparisons with builtin types.10816 if (const auto *CL = dyn_cast<CallExpr>(LeftExprSansParen);10817 CL && CL->getBuiltinCallee())10818 return;10819 10820 if (const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);10821 CR && CR->getBuiltinCallee())10822 return;10823 10824 // Emit the diagnostic.10825 Diag(Loc, diag::warn_floatingpoint_eq)10826 << LHS->getSourceRange() << RHS->getSourceRange();10827}10828 10829//===--- CHECK: Integer mixed-sign comparisons (-Wsign-compare) --------===//10830//===--- CHECK: Lossy implicit conversions (-Wconversion) --------------===//10831 10832namespace {10833 10834/// Structure recording the 'active' range of an integer-valued10835/// expression.10836struct IntRange {10837 /// The number of bits active in the int. Note that this includes exactly one10838 /// sign bit if !NonNegative.10839 unsigned Width;10840 10841 /// True if the int is known not to have negative values. If so, all leading10842 /// bits before Width are known zero, otherwise they are known to be the10843 /// same as the MSB within Width.10844 bool NonNegative;10845 10846 IntRange(unsigned Width, bool NonNegative)10847 : Width(Width), NonNegative(NonNegative) {}10848 10849 /// Number of bits excluding the sign bit.10850 unsigned valueBits() const {10851 return NonNegative ? Width : Width - 1;10852 }10853 10854 /// Returns the range of the bool type.10855 static IntRange forBoolType() {10856 return IntRange(1, true);10857 }10858 10859 /// Returns the range of an opaque value of the given integral type.10860 static IntRange forValueOfType(ASTContext &C, QualType T) {10861 return forValueOfCanonicalType(C,10862 T->getCanonicalTypeInternal().getTypePtr());10863 }10864 10865 /// Returns the range of an opaque value of a canonical integral type.10866 static IntRange forValueOfCanonicalType(ASTContext &C, const Type *T) {10867 assert(T->isCanonicalUnqualified());10868 10869 if (const auto *VT = dyn_cast<VectorType>(T))10870 T = VT->getElementType().getTypePtr();10871 if (const auto *CT = dyn_cast<ComplexType>(T))10872 T = CT->getElementType().getTypePtr();10873 if (const auto *AT = dyn_cast<AtomicType>(T))10874 T = AT->getValueType().getTypePtr();10875 10876 if (!C.getLangOpts().CPlusPlus) {10877 // For enum types in C code, use the underlying datatype.10878 if (const auto *ED = T->getAsEnumDecl())10879 T = ED->getIntegerType().getDesugaredType(C).getTypePtr();10880 } else if (auto *Enum = T->getAsEnumDecl()) {10881 // For enum types in C++, use the known bit width of the enumerators.10882 // In C++11, enums can have a fixed underlying type. Use this type to10883 // compute the range.10884 if (Enum->isFixed()) {10885 return IntRange(C.getIntWidth(QualType(T, 0)),10886 !Enum->getIntegerType()->isSignedIntegerType());10887 }10888 10889 unsigned NumPositive = Enum->getNumPositiveBits();10890 unsigned NumNegative = Enum->getNumNegativeBits();10891 10892 if (NumNegative == 0)10893 return IntRange(NumPositive, true/*NonNegative*/);10894 else10895 return IntRange(std::max(NumPositive + 1, NumNegative),10896 false/*NonNegative*/);10897 }10898 10899 if (const auto *EIT = dyn_cast<BitIntType>(T))10900 return IntRange(EIT->getNumBits(), EIT->isUnsigned());10901 10902 const BuiltinType *BT = cast<BuiltinType>(T);10903 assert(BT->isInteger());10904 10905 return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger());10906 }10907 10908 /// Returns the "target" range of a canonical integral type, i.e.10909 /// the range of values expressible in the type.10910 ///10911 /// This matches forValueOfCanonicalType except that enums have the10912 /// full range of their type, not the range of their enumerators.10913 static IntRange forTargetOfCanonicalType(ASTContext &C, const Type *T) {10914 assert(T->isCanonicalUnqualified());10915 10916 if (const VectorType *VT = dyn_cast<VectorType>(T))10917 T = VT->getElementType().getTypePtr();10918 if (const ComplexType *CT = dyn_cast<ComplexType>(T))10919 T = CT->getElementType().getTypePtr();10920 if (const AtomicType *AT = dyn_cast<AtomicType>(T))10921 T = AT->getValueType().getTypePtr();10922 if (const auto *ED = T->getAsEnumDecl())10923 T = C.getCanonicalType(ED->getIntegerType()).getTypePtr();10924 10925 if (const auto *EIT = dyn_cast<BitIntType>(T))10926 return IntRange(EIT->getNumBits(), EIT->isUnsigned());10927 10928 const BuiltinType *BT = cast<BuiltinType>(T);10929 assert(BT->isInteger());10930 10931 return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger());10932 }10933 10934 /// Returns the supremum of two ranges: i.e. their conservative merge.10935 static IntRange join(IntRange L, IntRange R) {10936 bool Unsigned = L.NonNegative && R.NonNegative;10937 return IntRange(std::max(L.valueBits(), R.valueBits()) + !Unsigned,10938 L.NonNegative && R.NonNegative);10939 }10940 10941 /// Return the range of a bitwise-AND of the two ranges.10942 static IntRange bit_and(IntRange L, IntRange R) {10943 unsigned Bits = std::max(L.Width, R.Width);10944 bool NonNegative = false;10945 if (L.NonNegative) {10946 Bits = std::min(Bits, L.Width);10947 NonNegative = true;10948 }10949 if (R.NonNegative) {10950 Bits = std::min(Bits, R.Width);10951 NonNegative = true;10952 }10953 return IntRange(Bits, NonNegative);10954 }10955 10956 /// Return the range of a sum of the two ranges.10957 static IntRange sum(IntRange L, IntRange R) {10958 bool Unsigned = L.NonNegative && R.NonNegative;10959 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !Unsigned,10960 Unsigned);10961 }10962 10963 /// Return the range of a difference of the two ranges.10964 static IntRange difference(IntRange L, IntRange R) {10965 // We need a 1-bit-wider range if:10966 // 1) LHS can be negative: least value can be reduced.10967 // 2) RHS can be negative: greatest value can be increased.10968 bool CanWiden = !L.NonNegative || !R.NonNegative;10969 bool Unsigned = L.NonNegative && R.Width == 0;10970 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +10971 !Unsigned,10972 Unsigned);10973 }10974 10975 /// Return the range of a product of the two ranges.10976 static IntRange product(IntRange L, IntRange R) {10977 // If both LHS and RHS can be negative, we can form10978 // -2^L * -2^R = 2^(L + R)10979 // which requires L + R + 1 value bits to represent.10980 bool CanWiden = !L.NonNegative && !R.NonNegative;10981 bool Unsigned = L.NonNegative && R.NonNegative;10982 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !Unsigned,10983 Unsigned);10984 }10985 10986 /// Return the range of a remainder operation between the two ranges.10987 static IntRange rem(IntRange L, IntRange R) {10988 // The result of a remainder can't be larger than the result of10989 // either side. The sign of the result is the sign of the LHS.10990 bool Unsigned = L.NonNegative;10991 return IntRange(std::min(L.valueBits(), R.valueBits()) + !Unsigned,10992 Unsigned);10993 }10994};10995 10996} // namespace10997 10998static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth) {10999 if (value.isSigned() && value.isNegative())11000 return IntRange(value.getSignificantBits(), false);11001 11002 if (value.getBitWidth() > MaxWidth)11003 value = value.trunc(MaxWidth);11004 11005 // isNonNegative() just checks the sign bit without considering11006 // signedness.11007 return IntRange(value.getActiveBits(), true);11008}11009 11010static IntRange GetValueRange(APValue &result, QualType Ty, unsigned MaxWidth) {11011 if (result.isInt())11012 return GetValueRange(result.getInt(), MaxWidth);11013 11014 if (result.isVector()) {11015 IntRange R = GetValueRange(result.getVectorElt(0), Ty, MaxWidth);11016 for (unsigned i = 1, e = result.getVectorLength(); i != e; ++i) {11017 IntRange El = GetValueRange(result.getVectorElt(i), Ty, MaxWidth);11018 R = IntRange::join(R, El);11019 }11020 return R;11021 }11022 11023 if (result.isComplexInt()) {11024 IntRange R = GetValueRange(result.getComplexIntReal(), MaxWidth);11025 IntRange I = GetValueRange(result.getComplexIntImag(), MaxWidth);11026 return IntRange::join(R, I);11027 }11028 11029 // This can happen with lossless casts to intptr_t of "based" lvalues.11030 // Assume it might use arbitrary bits.11031 // FIXME: The only reason we need to pass the type in here is to get11032 // the sign right on this one case. It would be nice if APValue11033 // preserved this.11034 assert(result.isLValue() || result.isAddrLabelDiff());11035 return IntRange(MaxWidth, Ty->isUnsignedIntegerOrEnumerationType());11036}11037 11038static QualType GetExprType(const Expr *E) {11039 QualType Ty = E->getType();11040 if (const auto *AtomicRHS = Ty->getAs<AtomicType>())11041 Ty = AtomicRHS->getValueType();11042 return Ty;11043}11044 11045/// Attempts to estimate an approximate range for the given integer expression.11046/// Returns a range if successful, otherwise it returns \c std::nullopt if a11047/// reliable estimation cannot be determined.11048///11049/// \param MaxWidth The width to which the value will be truncated.11050/// \param InConstantContext If \c true, interpret the expression within a11051/// constant context.11052/// \param Approximate If \c true, provide a likely range of values by assuming11053/// that arithmetic on narrower types remains within those types.11054/// If \c false, return a range that includes all possible values11055/// resulting from the expression.11056/// \returns A range of values that the expression might take, or11057/// std::nullopt if a reliable estimation cannot be determined.11058static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,11059 unsigned MaxWidth,11060 bool InConstantContext,11061 bool Approximate) {11062 E = E->IgnoreParens();11063 11064 // Try a full evaluation first.11065 Expr::EvalResult result;11066 if (E->EvaluateAsRValue(result, C, InConstantContext))11067 return GetValueRange(result.Val, GetExprType(E), MaxWidth);11068 11069 // I think we only want to look through implicit casts here; if the11070 // user has an explicit widening cast, we should treat the value as11071 // being of the new, wider type.11072 if (const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {11073 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)11074 return TryGetExprRange(C, CE->getSubExpr(), MaxWidth, InConstantContext,11075 Approximate);11076 11077 IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE));11078 11079 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||11080 CE->getCastKind() == CK_BooleanToSignedIntegral;11081 11082 // Assume that non-integer casts can span the full range of the type.11083 if (!isIntegerCast)11084 return OutputTypeRange;11085 11086 std::optional<IntRange> SubRange = TryGetExprRange(11087 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),11088 InConstantContext, Approximate);11089 if (!SubRange)11090 return std::nullopt;11091 11092 // Bail out if the subexpr's range is as wide as the cast type.11093 if (SubRange->Width >= OutputTypeRange.Width)11094 return OutputTypeRange;11095 11096 // Otherwise, we take the smaller width, and we're non-negative if11097 // either the output type or the subexpr is.11098 return IntRange(SubRange->Width,11099 SubRange->NonNegative || OutputTypeRange.NonNegative);11100 }11101 11102 if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {11103 // If we can fold the condition, just take that operand.11104 bool CondResult;11105 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C))11106 return TryGetExprRange(11107 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,11108 InConstantContext, Approximate);11109 11110 // Otherwise, conservatively merge.11111 // TryGetExprRange requires an integer expression, but a throw expression11112 // results in a void type.11113 Expr *TrueExpr = CO->getTrueExpr();11114 if (TrueExpr->getType()->isVoidType())11115 return std::nullopt;11116 11117 std::optional<IntRange> L =11118 TryGetExprRange(C, TrueExpr, MaxWidth, InConstantContext, Approximate);11119 if (!L)11120 return std::nullopt;11121 11122 Expr *FalseExpr = CO->getFalseExpr();11123 if (FalseExpr->getType()->isVoidType())11124 return std::nullopt;11125 11126 std::optional<IntRange> R =11127 TryGetExprRange(C, FalseExpr, MaxWidth, InConstantContext, Approximate);11128 if (!R)11129 return std::nullopt;11130 11131 return IntRange::join(*L, *R);11132 }11133 11134 if (const auto *BO = dyn_cast<BinaryOperator>(E)) {11135 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;11136 11137 switch (BO->getOpcode()) {11138 case BO_Cmp:11139 llvm_unreachable("builtin <=> should have class type");11140 11141 // Boolean-valued operations are single-bit and positive.11142 case BO_LAnd:11143 case BO_LOr:11144 case BO_LT:11145 case BO_GT:11146 case BO_LE:11147 case BO_GE:11148 case BO_EQ:11149 case BO_NE:11150 return IntRange::forBoolType();11151 11152 // The type of the assignments is the type of the LHS, so the RHS11153 // is not necessarily the same type.11154 case BO_MulAssign:11155 case BO_DivAssign:11156 case BO_RemAssign:11157 case BO_AddAssign:11158 case BO_SubAssign:11159 case BO_XorAssign:11160 case BO_OrAssign:11161 // TODO: bitfields?11162 return IntRange::forValueOfType(C, GetExprType(E));11163 11164 // Simple assignments just pass through the RHS, which will have11165 // been coerced to the LHS type.11166 case BO_Assign:11167 // TODO: bitfields?11168 return TryGetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext,11169 Approximate);11170 11171 // Operations with opaque sources are black-listed.11172 case BO_PtrMemD:11173 case BO_PtrMemI:11174 return IntRange::forValueOfType(C, GetExprType(E));11175 11176 // Bitwise-and uses the *infinum* of the two source ranges.11177 case BO_And:11178 case BO_AndAssign:11179 Combine = IntRange::bit_and;11180 break;11181 11182 // Left shift gets black-listed based on a judgement call.11183 case BO_Shl:11184 // ...except that we want to treat '1 << (blah)' as logically11185 // positive. It's an important idiom.11186 if (IntegerLiteral *I11187 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {11188 if (I->getValue() == 1) {11189 IntRange R = IntRange::forValueOfType(C, GetExprType(E));11190 return IntRange(R.Width, /*NonNegative*/ true);11191 }11192 }11193 [[fallthrough]];11194 11195 case BO_ShlAssign:11196 return IntRange::forValueOfType(C, GetExprType(E));11197 11198 // Right shift by a constant can narrow its left argument.11199 case BO_Shr:11200 case BO_ShrAssign: {11201 std::optional<IntRange> L = TryGetExprRange(11202 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);11203 if (!L)11204 return std::nullopt;11205 11206 // If the shift amount is a positive constant, drop the width by11207 // that much.11208 if (std::optional<llvm::APSInt> shift =11209 BO->getRHS()->getIntegerConstantExpr(C)) {11210 if (shift->isNonNegative()) {11211 if (shift->uge(L->Width))11212 L->Width = (L->NonNegative ? 0 : 1);11213 else11214 L->Width -= shift->getZExtValue();11215 }11216 }11217 11218 return L;11219 }11220 11221 // Comma acts as its right operand.11222 case BO_Comma:11223 return TryGetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext,11224 Approximate);11225 11226 case BO_Add:11227 if (!Approximate)11228 Combine = IntRange::sum;11229 break;11230 11231 case BO_Sub:11232 if (BO->getLHS()->getType()->isPointerType())11233 return IntRange::forValueOfType(C, GetExprType(E));11234 if (!Approximate)11235 Combine = IntRange::difference;11236 break;11237 11238 case BO_Mul:11239 if (!Approximate)11240 Combine = IntRange::product;11241 break;11242 11243 // The width of a division result is mostly determined by the size11244 // of the LHS.11245 case BO_Div: {11246 // Don't 'pre-truncate' the operands.11247 unsigned opWidth = C.getIntWidth(GetExprType(E));11248 std::optional<IntRange> L = TryGetExprRange(11249 C, BO->getLHS(), opWidth, InConstantContext, Approximate);11250 if (!L)11251 return std::nullopt;11252 11253 // If the divisor is constant, use that.11254 if (std::optional<llvm::APSInt> divisor =11255 BO->getRHS()->getIntegerConstantExpr(C)) {11256 unsigned log2 = divisor->logBase2(); // floor(log_2(divisor))11257 if (log2 >= L->Width)11258 L->Width = (L->NonNegative ? 0 : 1);11259 else11260 L->Width = std::min(L->Width - log2, MaxWidth);11261 return L;11262 }11263 11264 // Otherwise, just use the LHS's width.11265 // FIXME: This is wrong if the LHS could be its minimal value and the RHS11266 // could be -1.11267 std::optional<IntRange> R = TryGetExprRange(11268 C, BO->getRHS(), opWidth, InConstantContext, Approximate);11269 if (!R)11270 return std::nullopt;11271 11272 return IntRange(L->Width, L->NonNegative && R->NonNegative);11273 }11274 11275 case BO_Rem:11276 Combine = IntRange::rem;11277 break;11278 11279 // The default behavior is okay for these.11280 case BO_Xor:11281 case BO_Or:11282 break;11283 }11284 11285 // Combine the two ranges, but limit the result to the type in which we11286 // performed the computation.11287 QualType T = GetExprType(E);11288 unsigned opWidth = C.getIntWidth(T);11289 std::optional<IntRange> L = TryGetExprRange(C, BO->getLHS(), opWidth,11290 InConstantContext, Approximate);11291 if (!L)11292 return std::nullopt;11293 11294 std::optional<IntRange> R = TryGetExprRange(C, BO->getRHS(), opWidth,11295 InConstantContext, Approximate);11296 if (!R)11297 return std::nullopt;11298 11299 IntRange C = Combine(*L, *R);11300 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();11301 C.Width = std::min(C.Width, MaxWidth);11302 return C;11303 }11304 11305 if (const auto *UO = dyn_cast<UnaryOperator>(E)) {11306 switch (UO->getOpcode()) {11307 // Boolean-valued operations are white-listed.11308 case UO_LNot:11309 return IntRange::forBoolType();11310 11311 // Operations with opaque sources are black-listed.11312 case UO_Deref:11313 case UO_AddrOf: // should be impossible11314 return IntRange::forValueOfType(C, GetExprType(E));11315 11316 case UO_Minus: {11317 if (E->getType()->isUnsignedIntegerType()) {11318 return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,11319 Approximate);11320 }11321 11322 std::optional<IntRange> SubRange = TryGetExprRange(11323 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);11324 11325 if (!SubRange)11326 return std::nullopt;11327 11328 // If the range was previously non-negative, we need an extra bit for the11329 // sign bit. Otherwise, we need an extra bit because the negation of the11330 // most-negative value is one bit wider than that value.11331 return IntRange(std::min(SubRange->Width + 1, MaxWidth), false);11332 }11333 11334 case UO_Not: {11335 if (E->getType()->isUnsignedIntegerType()) {11336 return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,11337 Approximate);11338 }11339 11340 std::optional<IntRange> SubRange = TryGetExprRange(11341 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);11342 11343 if (!SubRange)11344 return std::nullopt;11345 11346 // The width increments by 1 if the sub-expression cannot be negative11347 // since it now can be.11348 return IntRange(11349 std::min(SubRange->Width + (int)SubRange->NonNegative, MaxWidth),11350 false);11351 }11352 11353 default:11354 return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,11355 Approximate);11356 }11357 }11358 11359 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))11360 return TryGetExprRange(C, OVE->getSourceExpr(), MaxWidth, InConstantContext,11361 Approximate);11362 11363 if (const auto *BitField = E->getSourceBitField())11364 return IntRange(BitField->getBitWidthValue(),11365 BitField->getType()->isUnsignedIntegerOrEnumerationType());11366 11367 if (GetExprType(E)->isVoidType())11368 return std::nullopt;11369 11370 return IntRange::forValueOfType(C, GetExprType(E));11371}11372 11373static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,11374 bool InConstantContext,11375 bool Approximate) {11376 return TryGetExprRange(C, E, C.getIntWidth(GetExprType(E)), InConstantContext,11377 Approximate);11378}11379 11380/// Checks whether the given value, which currently has the given11381/// source semantics, has the same value when coerced through the11382/// target semantics.11383static bool IsSameFloatAfterCast(const llvm::APFloat &value,11384 const llvm::fltSemantics &Src,11385 const llvm::fltSemantics &Tgt) {11386 llvm::APFloat truncated = value;11387 11388 bool ignored;11389 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);11390 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);11391 11392 return truncated.bitwiseIsEqual(value);11393}11394 11395/// Checks whether the given value, which currently has the given11396/// source semantics, has the same value when coerced through the11397/// target semantics.11398///11399/// The value might be a vector of floats (or a complex number).11400static bool IsSameFloatAfterCast(const APValue &value,11401 const llvm::fltSemantics &Src,11402 const llvm::fltSemantics &Tgt) {11403 if (value.isFloat())11404 return IsSameFloatAfterCast(value.getFloat(), Src, Tgt);11405 11406 if (value.isVector()) {11407 for (unsigned i = 0, e = value.getVectorLength(); i != e; ++i)11408 if (!IsSameFloatAfterCast(value.getVectorElt(i), Src, Tgt))11409 return false;11410 return true;11411 }11412 11413 assert(value.isComplexFloat());11414 return (IsSameFloatAfterCast(value.getComplexFloatReal(), Src, Tgt) &&11415 IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt));11416}11417 11418static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC,11419 bool IsListInit = false);11420 11421static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E) {11422 // Suppress cases where we are comparing against an enum constant.11423 if (const auto *DR = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))11424 if (isa<EnumConstantDecl>(DR->getDecl()))11425 return true;11426 11427 // Suppress cases where the value is expanded from a macro, unless that macro11428 // is how a language represents a boolean literal. This is the case in both C11429 // and Objective-C.11430 SourceLocation BeginLoc = E->getBeginLoc();11431 if (BeginLoc.isMacroID()) {11432 StringRef MacroName = Lexer::getImmediateMacroName(11433 BeginLoc, S.getSourceManager(), S.getLangOpts());11434 return MacroName != "YES" && MacroName != "NO" &&11435 MacroName != "true" && MacroName != "false";11436 }11437 11438 return false;11439}11440 11441static bool isKnownToHaveUnsignedValue(const Expr *E) {11442 return E->getType()->isIntegerType() &&11443 (!E->getType()->isSignedIntegerType() ||11444 !E->IgnoreParenImpCasts()->getType()->isSignedIntegerType());11445}11446 11447namespace {11448/// The promoted range of values of a type. In general this has the11449/// following structure:11450///11451/// |-----------| . . . |-----------|11452/// ^ ^ ^ ^11453/// Min HoleMin HoleMax Max11454///11455/// ... where there is only a hole if a signed type is promoted to unsigned11456/// (in which case Min and Max are the smallest and largest representable11457/// values).11458struct PromotedRange {11459 // Min, or HoleMax if there is a hole.11460 llvm::APSInt PromotedMin;11461 // Max, or HoleMin if there is a hole.11462 llvm::APSInt PromotedMax;11463 11464 PromotedRange(IntRange R, unsigned BitWidth, bool Unsigned) {11465 if (R.Width == 0)11466 PromotedMin = PromotedMax = llvm::APSInt(BitWidth, Unsigned);11467 else if (R.Width >= BitWidth && !Unsigned) {11468 // Promotion made the type *narrower*. This happens when promoting11469 // a < 32-bit unsigned / <= 32-bit signed bit-field to 'signed int'.11470 // Treat all values of 'signed int' as being in range for now.11471 PromotedMin = llvm::APSInt::getMinValue(BitWidth, Unsigned);11472 PromotedMax = llvm::APSInt::getMaxValue(BitWidth, Unsigned);11473 } else {11474 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)11475 .extOrTrunc(BitWidth);11476 PromotedMin.setIsUnsigned(Unsigned);11477 11478 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)11479 .extOrTrunc(BitWidth);11480 PromotedMax.setIsUnsigned(Unsigned);11481 }11482 }11483 11484 // Determine whether this range is contiguous (has no hole).11485 bool isContiguous() const { return PromotedMin <= PromotedMax; }11486 11487 // Where a constant value is within the range.11488 enum ComparisonResult {11489 LT = 0x1,11490 LE = 0x2,11491 GT = 0x4,11492 GE = 0x8,11493 EQ = 0x10,11494 NE = 0x20,11495 InRangeFlag = 0x40,11496 11497 Less = LE | LT | NE,11498 Min = LE | InRangeFlag,11499 InRange = InRangeFlag,11500 Max = GE | InRangeFlag,11501 Greater = GE | GT | NE,11502 11503 OnlyValue = LE | GE | EQ | InRangeFlag,11504 InHole = NE11505 };11506 11507 ComparisonResult compare(const llvm::APSInt &Value) const {11508 assert(Value.getBitWidth() == PromotedMin.getBitWidth() &&11509 Value.isUnsigned() == PromotedMin.isUnsigned());11510 if (!isContiguous()) {11511 assert(Value.isUnsigned() && "discontiguous range for signed compare");11512 if (Value.isMinValue()) return Min;11513 if (Value.isMaxValue()) return Max;11514 if (Value >= PromotedMin) return InRange;11515 if (Value <= PromotedMax) return InRange;11516 return InHole;11517 }11518 11519 switch (llvm::APSInt::compareValues(Value, PromotedMin)) {11520 case -1: return Less;11521 case 0: return PromotedMin == PromotedMax ? OnlyValue : Min;11522 case 1:11523 switch (llvm::APSInt::compareValues(Value, PromotedMax)) {11524 case -1: return InRange;11525 case 0: return Max;11526 case 1: return Greater;11527 }11528 }11529 11530 llvm_unreachable("impossible compare result");11531 }11532 11533 static std::optional<StringRef>11534 constantValue(BinaryOperatorKind Op, ComparisonResult R, bool ConstantOnRHS) {11535 if (Op == BO_Cmp) {11536 ComparisonResult LTFlag = LT, GTFlag = GT;11537 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);11538 11539 if (R & EQ) return StringRef("'std::strong_ordering::equal'");11540 if (R & LTFlag) return StringRef("'std::strong_ordering::less'");11541 if (R & GTFlag) return StringRef("'std::strong_ordering::greater'");11542 return std::nullopt;11543 }11544 11545 ComparisonResult TrueFlag, FalseFlag;11546 if (Op == BO_EQ) {11547 TrueFlag = EQ;11548 FalseFlag = NE;11549 } else if (Op == BO_NE) {11550 TrueFlag = NE;11551 FalseFlag = EQ;11552 } else {11553 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {11554 TrueFlag = LT;11555 FalseFlag = GE;11556 } else {11557 TrueFlag = GT;11558 FalseFlag = LE;11559 }11560 if (Op == BO_GE || Op == BO_LE)11561 std::swap(TrueFlag, FalseFlag);11562 }11563 if (R & TrueFlag)11564 return StringRef("true");11565 if (R & FalseFlag)11566 return StringRef("false");11567 return std::nullopt;11568 }11569};11570}11571 11572static bool HasEnumType(const Expr *E) {11573 // Strip off implicit integral promotions.11574 while (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {11575 if (ICE->getCastKind() != CK_IntegralCast &&11576 ICE->getCastKind() != CK_NoOp)11577 break;11578 E = ICE->getSubExpr();11579 }11580 11581 return E->getType()->isEnumeralType();11582}11583 11584static int classifyConstantValue(Expr *Constant) {11585 // The values of this enumeration are used in the diagnostics11586 // diag::warn_out_of_range_compare and diag::warn_tautological_bool_compare.11587 enum ConstantValueKind {11588 Miscellaneous = 0,11589 LiteralTrue,11590 LiteralFalse11591 };11592 if (auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))11593 return BL->getValue() ? ConstantValueKind::LiteralTrue11594 : ConstantValueKind::LiteralFalse;11595 return ConstantValueKind::Miscellaneous;11596}11597 11598static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E,11599 Expr *Constant, Expr *Other,11600 const llvm::APSInt &Value,11601 bool RhsConstant) {11602 if (S.inTemplateInstantiation())11603 return false;11604 11605 Expr *OriginalOther = Other;11606 11607 Constant = Constant->IgnoreParenImpCasts();11608 Other = Other->IgnoreParenImpCasts();11609 11610 // Suppress warnings on tautological comparisons between values of the same11611 // enumeration type. There are only two ways we could warn on this:11612 // - If the constant is outside the range of representable values of11613 // the enumeration. In such a case, we should warn about the cast11614 // to enumeration type, not about the comparison.11615 // - If the constant is the maximum / minimum in-range value. For an11616 // enumeratin type, such comparisons can be meaningful and useful.11617 if (Constant->getType()->isEnumeralType() &&11618 S.Context.hasSameUnqualifiedType(Constant->getType(), Other->getType()))11619 return false;11620 11621 std::optional<IntRange> OtherValueRange = TryGetExprRange(11622 S.Context, Other, S.isConstantEvaluatedContext(), /*Approximate=*/false);11623 if (!OtherValueRange)11624 return false;11625 11626 QualType OtherT = Other->getType();11627 if (const auto *AT = OtherT->getAs<AtomicType>())11628 OtherT = AT->getValueType();11629 IntRange OtherTypeRange = IntRange::forValueOfType(S.Context, OtherT);11630 11631 // Special case for ObjC BOOL on targets where its a typedef for a signed char11632 // (Namely, macOS). FIXME: IntRange::forValueOfType should do this.11633 bool IsObjCSignedCharBool = S.getLangOpts().ObjC &&11634 S.ObjC().NSAPIObj->isObjCBOOLType(OtherT) &&11635 OtherT->isSpecificBuiltinType(BuiltinType::SChar);11636 11637 // Whether we're treating Other as being a bool because of the form of11638 // expression despite it having another type (typically 'int' in C).11639 bool OtherIsBooleanDespiteType =11640 !OtherT->isBooleanType() && Other->isKnownToHaveBooleanValue();11641 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)11642 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();11643 11644 // Check if all values in the range of possible values of this expression11645 // lead to the same comparison outcome.11646 PromotedRange OtherPromotedValueRange(*OtherValueRange, Value.getBitWidth(),11647 Value.isUnsigned());11648 auto Cmp = OtherPromotedValueRange.compare(Value);11649 auto Result = PromotedRange::constantValue(E->getOpcode(), Cmp, RhsConstant);11650 if (!Result)11651 return false;11652 11653 // Also consider the range determined by the type alone. This allows us to11654 // classify the warning under the proper diagnostic group.11655 bool TautologicalTypeCompare = false;11656 {11657 PromotedRange OtherPromotedTypeRange(OtherTypeRange, Value.getBitWidth(),11658 Value.isUnsigned());11659 auto TypeCmp = OtherPromotedTypeRange.compare(Value);11660 if (auto TypeResult = PromotedRange::constantValue(E->getOpcode(), TypeCmp,11661 RhsConstant)) {11662 TautologicalTypeCompare = true;11663 Cmp = TypeCmp;11664 Result = TypeResult;11665 }11666 }11667 11668 // Don't warn if the non-constant operand actually always evaluates to the11669 // same value.11670 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)11671 return false;11672 11673 // Suppress the diagnostic for an in-range comparison if the constant comes11674 // from a macro or enumerator. We don't want to diagnose11675 //11676 // some_long_value <= INT_MAX11677 //11678 // when sizeof(int) == sizeof(long).11679 bool InRange = Cmp & PromotedRange::InRangeFlag;11680 if (InRange && IsEnumConstOrFromMacro(S, Constant))11681 return false;11682 11683 // A comparison of an unsigned bit-field against 0 is really a type problem,11684 // even though at the type level the bit-field might promote to 'signed int'.11685 if (Other->refersToBitField() && InRange && Value == 0 &&11686 Other->getType()->isUnsignedIntegerOrEnumerationType())11687 TautologicalTypeCompare = true;11688 11689 // If this is a comparison to an enum constant, include that11690 // constant in the diagnostic.11691 const EnumConstantDecl *ED = nullptr;11692 if (const auto *DR = dyn_cast<DeclRefExpr>(Constant))11693 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());11694 11695 // Should be enough for uint128 (39 decimal digits)11696 SmallString<64> PrettySourceValue;11697 llvm::raw_svector_ostream OS(PrettySourceValue);11698 if (ED) {11699 OS << '\'' << *ED << "' (" << Value << ")";11700 } else if (auto *BL = dyn_cast<ObjCBoolLiteralExpr>(11701 Constant->IgnoreParenImpCasts())) {11702 OS << (BL->getValue() ? "YES" : "NO");11703 } else {11704 OS << Value;11705 }11706 11707 if (!TautologicalTypeCompare) {11708 S.Diag(E->getOperatorLoc(), diag::warn_tautological_compare_value_range)11709 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative11710 << E->getOpcodeStr() << OS.str() << *Result11711 << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();11712 return true;11713 }11714 11715 if (IsObjCSignedCharBool) {11716 S.DiagRuntimeBehavior(E->getOperatorLoc(), E,11717 S.PDiag(diag::warn_tautological_compare_objc_bool)11718 << OS.str() << *Result);11719 return true;11720 }11721 11722 // FIXME: We use a somewhat different formatting for the in-range cases and11723 // cases involving boolean values for historical reasons. We should pick a11724 // consistent way of presenting these diagnostics.11725 if (!InRange || Other->isKnownToHaveBooleanValue()) {11726 11727 S.DiagRuntimeBehavior(11728 E->getOperatorLoc(), E,11729 S.PDiag(!InRange ? diag::warn_out_of_range_compare11730 : diag::warn_tautological_bool_compare)11731 << OS.str() << classifyConstantValue(Constant) << OtherT11732 << OtherIsBooleanDespiteType << *Result11733 << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange());11734 } else {11735 bool IsCharTy = OtherT.withoutLocalFastQualifiers() == S.Context.CharTy;11736 unsigned Diag =11737 (isKnownToHaveUnsignedValue(OriginalOther) && Value == 0)11738 ? (HasEnumType(OriginalOther)11739 ? diag::warn_unsigned_enum_always_true_comparison11740 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison11741 : diag::warn_unsigned_always_true_comparison)11742 : diag::warn_tautological_constant_compare;11743 11744 S.Diag(E->getOperatorLoc(), Diag)11745 << RhsConstant << OtherT << E->getOpcodeStr() << OS.str() << *Result11746 << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();11747 }11748 11749 return true;11750}11751 11752/// Analyze the operands of the given comparison. Implements the11753/// fallback case from AnalyzeComparison.11754static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) {11755 AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());11756 AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());11757}11758 11759/// Implements -Wsign-compare.11760///11761/// \param E the binary operator to check for warnings11762static void AnalyzeComparison(Sema &S, BinaryOperator *E) {11763 // The type the comparison is being performed in.11764 QualType T = E->getLHS()->getType();11765 11766 // Only analyze comparison operators where both sides have been converted to11767 // the same type.11768 if (!S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType()))11769 return AnalyzeImpConvsInComparison(S, E);11770 11771 // Don't analyze value-dependent comparisons directly.11772 if (E->isValueDependent())11773 return AnalyzeImpConvsInComparison(S, E);11774 11775 Expr *LHS = E->getLHS();11776 Expr *RHS = E->getRHS();11777 11778 if (T->isIntegralType(S.Context)) {11779 std::optional<llvm::APSInt> RHSValue =11780 RHS->getIntegerConstantExpr(S.Context);11781 std::optional<llvm::APSInt> LHSValue =11782 LHS->getIntegerConstantExpr(S.Context);11783 11784 // We don't care about expressions whose result is a constant.11785 if (RHSValue && LHSValue)11786 return AnalyzeImpConvsInComparison(S, E);11787 11788 // We only care about expressions where just one side is literal11789 if ((bool)RHSValue ^ (bool)LHSValue) {11790 // Is the constant on the RHS or LHS?11791 const bool RhsConstant = (bool)RHSValue;11792 Expr *Const = RhsConstant ? RHS : LHS;11793 Expr *Other = RhsConstant ? LHS : RHS;11794 const llvm::APSInt &Value = RhsConstant ? *RHSValue : *LHSValue;11795 11796 // Check whether an integer constant comparison results in a value11797 // of 'true' or 'false'.11798 if (CheckTautologicalComparison(S, E, Const, Other, Value, RhsConstant))11799 return AnalyzeImpConvsInComparison(S, E);11800 }11801 }11802 11803 if (!T->hasUnsignedIntegerRepresentation()) {11804 // We don't do anything special if this isn't an unsigned integral11805 // comparison: we're only interested in integral comparisons, and11806 // signed comparisons only happen in cases we don't care to warn about.11807 return AnalyzeImpConvsInComparison(S, E);11808 }11809 11810 LHS = LHS->IgnoreParenImpCasts();11811 RHS = RHS->IgnoreParenImpCasts();11812 11813 if (!S.getLangOpts().CPlusPlus) {11814 // Avoid warning about comparison of integers with different signs when11815 // RHS/LHS has a `typeof(E)` type whose sign is different from the sign of11816 // the type of `E`.11817 if (const auto *TET = dyn_cast<TypeOfExprType>(LHS->getType()))11818 LHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts();11819 if (const auto *TET = dyn_cast<TypeOfExprType>(RHS->getType()))11820 RHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts();11821 }11822 11823 // Check to see if one of the (unmodified) operands is of different11824 // signedness.11825 Expr *signedOperand, *unsignedOperand;11826 if (LHS->getType()->hasSignedIntegerRepresentation()) {11827 assert(!RHS->getType()->hasSignedIntegerRepresentation() &&11828 "unsigned comparison between two signed integer expressions?");11829 signedOperand = LHS;11830 unsignedOperand = RHS;11831 } else if (RHS->getType()->hasSignedIntegerRepresentation()) {11832 signedOperand = RHS;11833 unsignedOperand = LHS;11834 } else {11835 return AnalyzeImpConvsInComparison(S, E);11836 }11837 11838 // Otherwise, calculate the effective range of the signed operand.11839 std::optional<IntRange> signedRange =11840 TryGetExprRange(S.Context, signedOperand, S.isConstantEvaluatedContext(),11841 /*Approximate=*/true);11842 if (!signedRange)11843 return;11844 11845 // Go ahead and analyze implicit conversions in the operands. Note11846 // that we skip the implicit conversions on both sides.11847 AnalyzeImplicitConversions(S, LHS, E->getOperatorLoc());11848 AnalyzeImplicitConversions(S, RHS, E->getOperatorLoc());11849 11850 // If the signed range is non-negative, -Wsign-compare won't fire.11851 if (signedRange->NonNegative)11852 return;11853 11854 // For (in)equality comparisons, if the unsigned operand is a11855 // constant which cannot collide with a overflowed signed operand,11856 // then reinterpreting the signed operand as unsigned will not11857 // change the result of the comparison.11858 if (E->isEqualityOp()) {11859 unsigned comparisonWidth = S.Context.getIntWidth(T);11860 std::optional<IntRange> unsignedRange = TryGetExprRange(11861 S.Context, unsignedOperand, S.isConstantEvaluatedContext(),11862 /*Approximate=*/true);11863 if (!unsignedRange)11864 return;11865 11866 // We should never be unable to prove that the unsigned operand is11867 // non-negative.11868 assert(unsignedRange->NonNegative && "unsigned range includes negative?");11869 11870 if (unsignedRange->Width < comparisonWidth)11871 return;11872 }11873 11874 S.DiagRuntimeBehavior(E->getOperatorLoc(), E,11875 S.PDiag(diag::warn_mixed_sign_comparison)11876 << LHS->getType() << RHS->getType()11877 << LHS->getSourceRange() << RHS->getSourceRange());11878}11879 11880/// Analyzes an attempt to assign the given value to a bitfield.11881///11882/// Returns true if there was something fishy about the attempt.11883static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,11884 SourceLocation InitLoc) {11885 assert(Bitfield->isBitField());11886 if (Bitfield->isInvalidDecl())11887 return false;11888 11889 // White-list bool bitfields.11890 QualType BitfieldType = Bitfield->getType();11891 if (BitfieldType->isBooleanType())11892 return false;11893 11894 if (auto *BitfieldEnumDecl = BitfieldType->getAsEnumDecl()) {11895 // If the underlying enum type was not explicitly specified as an unsigned11896 // type and the enum contain only positive values, MSVC++ will cause an11897 // inconsistency by storing this as a signed type.11898 if (S.getLangOpts().CPlusPlus11 &&11899 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&11900 BitfieldEnumDecl->getNumPositiveBits() > 0 &&11901 BitfieldEnumDecl->getNumNegativeBits() == 0) {11902 S.Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)11903 << BitfieldEnumDecl;11904 }11905 }11906 11907 // Ignore value- or type-dependent expressions.11908 if (Bitfield->getBitWidth()->isValueDependent() ||11909 Bitfield->getBitWidth()->isTypeDependent() ||11910 Init->isValueDependent() ||11911 Init->isTypeDependent())11912 return false;11913 11914 Expr *OriginalInit = Init->IgnoreParenImpCasts();11915 unsigned FieldWidth = Bitfield->getBitWidthValue();11916 11917 Expr::EvalResult Result;11918 if (!OriginalInit->EvaluateAsInt(Result, S.Context,11919 Expr::SE_AllowSideEffects)) {11920 // The RHS is not constant. If the RHS has an enum type, make sure the11921 // bitfield is wide enough to hold all the values of the enum without11922 // truncation.11923 const auto *ED = OriginalInit->getType()->getAsEnumDecl();11924 const PreferredTypeAttr *PTAttr = nullptr;11925 if (!ED) {11926 PTAttr = Bitfield->getAttr<PreferredTypeAttr>();11927 if (PTAttr)11928 ED = PTAttr->getType()->getAsEnumDecl();11929 }11930 if (ED) {11931 bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType();11932 11933 // Enum types are implicitly signed on Windows, so check if there are any11934 // negative enumerators to see if the enum was intended to be signed or11935 // not.11936 bool SignedEnum = ED->getNumNegativeBits() > 0;11937 11938 // Check for surprising sign changes when assigning enum values to a11939 // bitfield of different signedness. If the bitfield is signed and we11940 // have exactly the right number of bits to store this unsigned enum,11941 // suggest changing the enum to an unsigned type. This typically happens11942 // on Windows where unfixed enums always use an underlying type of 'int'.11943 unsigned DiagID = 0;11944 if (SignedEnum && !SignedBitfield) {11945 DiagID =11946 PTAttr == nullptr11947 ? diag::warn_unsigned_bitfield_assigned_signed_enum11948 : diag::11949 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;11950 } else if (SignedBitfield && !SignedEnum &&11951 ED->getNumPositiveBits() == FieldWidth) {11952 DiagID =11953 PTAttr == nullptr11954 ? diag::warn_signed_bitfield_enum_conversion11955 : diag::warn_preferred_type_signed_bitfield_enum_conversion;11956 }11957 if (DiagID) {11958 S.Diag(InitLoc, DiagID) << Bitfield << ED;11959 TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo();11960 SourceRange TypeRange =11961 TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange();11962 S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign)11963 << SignedEnum << TypeRange;11964 if (PTAttr)11965 S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)11966 << ED;11967 }11968 11969 // Compute the required bitwidth. If the enum has negative values, we need11970 // one more bit than the normal number of positive bits to represent the11971 // sign bit.11972 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,11973 ED->getNumNegativeBits())11974 : ED->getNumPositiveBits();11975 11976 // Check the bitwidth.11977 if (BitsNeeded > FieldWidth) {11978 Expr *WidthExpr = Bitfield->getBitWidth();11979 auto DiagID =11980 PTAttr == nullptr11981 ? diag::warn_bitfield_too_small_for_enum11982 : diag::warn_preferred_type_bitfield_too_small_for_enum;11983 S.Diag(InitLoc, DiagID) << Bitfield << ED;11984 S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)11985 << BitsNeeded << ED << WidthExpr->getSourceRange();11986 if (PTAttr)11987 S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)11988 << ED;11989 }11990 }11991 11992 return false;11993 }11994 11995 llvm::APSInt Value = Result.Val.getInt();11996 11997 unsigned OriginalWidth = Value.getBitWidth();11998 11999 // In C, the macro 'true' from stdbool.h will evaluate to '1'; To reduce12000 // false positives where the user is demonstrating they intend to use the12001 // bit-field as a Boolean, check to see if the value is 1 and we're assigning12002 // to a one-bit bit-field to see if the value came from a macro named 'true'.12003 bool OneAssignedToOneBitBitfield = FieldWidth == 1 && Value == 1;12004 if (OneAssignedToOneBitBitfield && !S.LangOpts.CPlusPlus) {12005 SourceLocation MaybeMacroLoc = OriginalInit->getBeginLoc();12006 if (S.SourceMgr.isInSystemMacro(MaybeMacroLoc) &&12007 S.findMacroSpelling(MaybeMacroLoc, "true"))12008 return false;12009 }12010 12011 if (!Value.isSigned() || Value.isNegative())12012 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))12013 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)12014 OriginalWidth = Value.getSignificantBits();12015 12016 if (OriginalWidth <= FieldWidth)12017 return false;12018 12019 // Compute the value which the bitfield will contain.12020 llvm::APSInt TruncatedValue = Value.trunc(FieldWidth);12021 TruncatedValue.setIsSigned(BitfieldType->isSignedIntegerType());12022 12023 // Check whether the stored value is equal to the original value.12024 TruncatedValue = TruncatedValue.extend(OriginalWidth);12025 if (llvm::APSInt::isSameValue(Value, TruncatedValue))12026 return false;12027 12028 std::string PrettyValue = toString(Value, 10);12029 std::string PrettyTrunc = toString(TruncatedValue, 10);12030 12031 S.Diag(InitLoc, OneAssignedToOneBitBitfield12032 ? diag::warn_impcast_single_bit_bitield_precision_constant12033 : diag::warn_impcast_bitfield_precision_constant)12034 << PrettyValue << PrettyTrunc << OriginalInit->getType()12035 << Init->getSourceRange();12036 12037 return true;12038}12039 12040/// Analyze the given simple or compound assignment for warning-worthy12041/// operations.12042static void AnalyzeAssignment(Sema &S, BinaryOperator *E) {12043 // Just recurse on the LHS.12044 AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());12045 12046 // We want to recurse on the RHS as normal unless we're assigning to12047 // a bitfield.12048 if (FieldDecl *Bitfield = E->getLHS()->getSourceBitField()) {12049 if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(),12050 E->getOperatorLoc())) {12051 // Recurse, ignoring any implicit conversions on the RHS.12052 return AnalyzeImplicitConversions(S, E->getRHS()->IgnoreParenImpCasts(),12053 E->getOperatorLoc());12054 }12055 }12056 12057 AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());12058 12059 // Diagnose implicitly sequentially-consistent atomic assignment.12060 if (E->getLHS()->getType()->isAtomicType())12061 S.Diag(E->getRHS()->getBeginLoc(), diag::warn_atomic_implicit_seq_cst);12062}12063 12064/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion.12065static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType,12066 QualType T, SourceLocation CContext, unsigned diag,12067 bool PruneControlFlow = false) {12068 // For languages like HLSL and OpenCL, implicit conversion diagnostics listing12069 // address space annotations isn't really useful. The warnings aren't because12070 // you're converting a `private int` to `unsigned int`, it is because you're12071 // conerting `int` to `unsigned int`.12072 if (SourceType.hasAddressSpace())12073 SourceType = S.getASTContext().removeAddrSpaceQualType(SourceType);12074 if (T.hasAddressSpace())12075 T = S.getASTContext().removeAddrSpaceQualType(T);12076 if (PruneControlFlow) {12077 S.DiagRuntimeBehavior(E->getExprLoc(), E,12078 S.PDiag(diag)12079 << SourceType << T << E->getSourceRange()12080 << SourceRange(CContext));12081 return;12082 }12083 S.Diag(E->getExprLoc(), diag)12084 << SourceType << T << E->getSourceRange() << SourceRange(CContext);12085}12086 12087/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion.12088static void DiagnoseImpCast(Sema &S, const Expr *E, QualType T,12089 SourceLocation CContext, unsigned diag,12090 bool PruneControlFlow = false) {12091 DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, PruneControlFlow);12092}12093 12094/// Diagnose an implicit cast from a floating point value to an integer value.12095static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T,12096 SourceLocation CContext) {12097 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);12098 bool PruneWarnings = S.inTemplateInstantiation();12099 12100 const Expr *InnerE = E->IgnoreParenImpCasts();12101 // We also want to warn on, e.g., "int i = -1.234"12102 if (const auto *UOp = dyn_cast<UnaryOperator>(InnerE))12103 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)12104 InnerE = UOp->getSubExpr()->IgnoreParenImpCasts();12105 12106 bool IsLiteral = isa<FloatingLiteral>(E) || isa<FloatingLiteral>(InnerE);12107 12108 llvm::APFloat Value(0.0);12109 bool IsConstant =12110 E->EvaluateAsFloat(Value, S.Context, Expr::SE_AllowSideEffects);12111 if (!IsConstant) {12112 if (S.ObjC().isSignedCharBool(T)) {12113 return S.ObjC().adornBoolConversionDiagWithTernaryFixit(12114 E, S.Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)12115 << E->getType());12116 }12117 12118 return DiagnoseImpCast(S, E, T, CContext,12119 diag::warn_impcast_float_integer, PruneWarnings);12120 }12121 12122 bool isExact = false;12123 12124 llvm::APSInt IntegerValue(S.Context.getIntWidth(T),12125 T->hasUnsignedIntegerRepresentation());12126 llvm::APFloat::opStatus Result = Value.convertToInteger(12127 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);12128 12129 // FIXME: Force the precision of the source value down so we don't print12130 // digits which are usually useless (we don't really care here if we12131 // truncate a digit by accident in edge cases). Ideally, APFloat::toString12132 // would automatically print the shortest representation, but it's a bit12133 // tricky to implement.12134 SmallString<16> PrettySourceValue;12135 unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics());12136 precision = (precision * 59 + 195) / 196;12137 Value.toString(PrettySourceValue, precision);12138 12139 if (S.ObjC().isSignedCharBool(T) && IntegerValue != 0 && IntegerValue != 1) {12140 return S.ObjC().adornBoolConversionDiagWithTernaryFixit(12141 E, S.Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)12142 << PrettySourceValue);12143 }12144 12145 if (Result == llvm::APFloat::opOK && isExact) {12146 if (IsLiteral) return;12147 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,12148 PruneWarnings);12149 }12150 12151 // Conversion of a floating-point value to a non-bool integer where the12152 // integral part cannot be represented by the integer type is undefined.12153 if (!IsBool && Result == llvm::APFloat::opInvalidOp)12154 return DiagnoseImpCast(12155 S, E, T, CContext,12156 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range12157 : diag::warn_impcast_float_to_integer_out_of_range,12158 PruneWarnings);12159 12160 unsigned DiagID = 0;12161 if (IsLiteral) {12162 // Warn on floating point literal to integer.12163 DiagID = diag::warn_impcast_literal_float_to_integer;12164 } else if (IntegerValue == 0) {12165 if (Value.isZero()) { // Skip -0.0 to 0 conversion.12166 return DiagnoseImpCast(S, E, T, CContext,12167 diag::warn_impcast_float_integer, PruneWarnings);12168 }12169 // Warn on non-zero to zero conversion.12170 DiagID = diag::warn_impcast_float_to_integer_zero;12171 } else {12172 if (IntegerValue.isUnsigned()) {12173 if (!IntegerValue.isMaxValue()) {12174 return DiagnoseImpCast(S, E, T, CContext,12175 diag::warn_impcast_float_integer, PruneWarnings);12176 }12177 } else { // IntegerValue.isSigned()12178 if (!IntegerValue.isMaxSignedValue() &&12179 !IntegerValue.isMinSignedValue()) {12180 return DiagnoseImpCast(S, E, T, CContext,12181 diag::warn_impcast_float_integer, PruneWarnings);12182 }12183 }12184 // Warn on evaluatable floating point expression to integer conversion.12185 DiagID = diag::warn_impcast_float_to_integer;12186 }12187 12188 SmallString<16> PrettyTargetValue;12189 if (IsBool)12190 PrettyTargetValue = Value.isZero() ? "false" : "true";12191 else12192 IntegerValue.toString(PrettyTargetValue);12193 12194 if (PruneWarnings) {12195 S.DiagRuntimeBehavior(E->getExprLoc(), E,12196 S.PDiag(DiagID)12197 << E->getType() << T.getUnqualifiedType()12198 << PrettySourceValue << PrettyTargetValue12199 << E->getSourceRange() << SourceRange(CContext));12200 } else {12201 S.Diag(E->getExprLoc(), DiagID)12202 << E->getType() << T.getUnqualifiedType() << PrettySourceValue12203 << PrettyTargetValue << E->getSourceRange() << SourceRange(CContext);12204 }12205}12206 12207/// Analyze the given compound assignment for the possible losing of12208/// floating-point precision.12209static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {12210 assert(isa<CompoundAssignOperator>(E) &&12211 "Must be compound assignment operation");12212 // Recurse on the LHS and RHS in here12213 AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());12214 AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());12215 12216 if (E->getLHS()->getType()->isAtomicType())12217 S.Diag(E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);12218 12219 // Now check the outermost expression12220 const auto *ResultBT = E->getLHS()->getType()->getAs<BuiltinType>();12221 const auto *RBT = cast<CompoundAssignOperator>(E)12222 ->getComputationResultType()12223 ->getAs<BuiltinType>();12224 12225 // The below checks assume source is floating point.12226 if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return;12227 12228 // If source is floating point but target is an integer.12229 if (ResultBT->isInteger())12230 return DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(),12231 E->getExprLoc(), diag::warn_impcast_float_integer);12232 12233 if (!ResultBT->isFloatingPoint())12234 return;12235 12236 // If both source and target are floating points, warn about losing precision.12237 int Order = S.getASTContext().getFloatingTypeSemanticOrder(12238 QualType(ResultBT, 0), QualType(RBT, 0));12239 if (Order < 0 && !S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))12240 // warn about dropping FP rank.12241 DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(),12242 diag::warn_impcast_float_result_precision);12243}12244 12245static std::string PrettyPrintInRange(const llvm::APSInt &Value,12246 IntRange Range) {12247 if (!Range.Width) return "0";12248 12249 llvm::APSInt ValueInRange = Value;12250 ValueInRange.setIsSigned(!Range.NonNegative);12251 ValueInRange = ValueInRange.trunc(Range.Width);12252 return toString(ValueInRange, 10);12253}12254 12255static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex,12256 bool ToBool) {12257 if (!isa<ImplicitCastExpr>(Ex))12258 return false;12259 12260 const Expr *InnerE = Ex->IgnoreParenImpCasts();12261 const Type *Target = S.Context.getCanonicalType(Ex->getType()).getTypePtr();12262 const Type *Source =12263 S.Context.getCanonicalType(InnerE->getType()).getTypePtr();12264 if (Target->isDependentType())12265 return false;12266 12267 const auto *FloatCandidateBT =12268 dyn_cast<BuiltinType>(ToBool ? Source : Target);12269 const Type *BoolCandidateType = ToBool ? Target : Source;12270 12271 return (BoolCandidateType->isSpecificBuiltinType(BuiltinType::Bool) &&12272 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));12273}12274 12275static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall,12276 SourceLocation CC) {12277 for (unsigned I = 0, N = TheCall->getNumArgs(); I < N; ++I) {12278 const Expr *CurrA = TheCall->getArg(I);12279 if (!IsImplicitBoolFloatConversion(S, CurrA, true))12280 continue;12281 12282 bool IsSwapped = ((I > 0) && IsImplicitBoolFloatConversion(12283 S, TheCall->getArg(I - 1), false));12284 IsSwapped |= ((I < (N - 1)) && IsImplicitBoolFloatConversion(12285 S, TheCall->getArg(I + 1), false));12286 if (IsSwapped) {12287 // Warn on this floating-point to bool conversion.12288 DiagnoseImpCast(S, CurrA->IgnoreParenImpCasts(),12289 CurrA->getType(), CC,12290 diag::warn_impcast_floating_point_to_bool);12291 }12292 }12293}12294 12295static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T,12296 SourceLocation CC) {12297 // Don't warn on functions which have return type nullptr_t.12298 if (isa<CallExpr>(E))12299 return;12300 12301 // Check for NULL (GNUNull) or nullptr (CXX11_nullptr).12302 const Expr *NewE = E->IgnoreParenImpCasts();12303 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);12304 bool HasNullPtrType = NewE->getType()->isNullPtrType();12305 if (!IsGNUNullExpr && !HasNullPtrType)12306 return;12307 12308 // Return if target type is a safe conversion.12309 if (T->isAnyPointerType() || T->isBlockPointerType() ||12310 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())12311 return;12312 12313 if (S.Diags.isIgnored(diag::warn_impcast_null_pointer_to_integer,12314 E->getExprLoc()))12315 return;12316 12317 SourceLocation Loc = E->getSourceRange().getBegin();12318 12319 // Venture through the macro stacks to get to the source of macro arguments.12320 // The new location is a better location than the complete location that was12321 // passed in.12322 Loc = S.SourceMgr.getTopMacroCallerLoc(Loc);12323 CC = S.SourceMgr.getTopMacroCallerLoc(CC);12324 12325 // __null is usually wrapped in a macro. Go up a macro if that is the case.12326 if (IsGNUNullExpr && Loc.isMacroID()) {12327 StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(12328 Loc, S.SourceMgr, S.getLangOpts());12329 if (MacroName == "NULL")12330 Loc = S.SourceMgr.getImmediateExpansionRange(Loc).getBegin();12331 }12332 12333 // Only warn if the null and context location are in the same macro expansion.12334 if (S.SourceMgr.getFileID(Loc) != S.SourceMgr.getFileID(CC))12335 return;12336 12337 S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer)12338 << HasNullPtrType << T << SourceRange(CC)12339 << FixItHint::CreateReplacement(Loc,12340 S.getFixItZeroLiteralForType(T, Loc));12341}12342 12343// Helper function to filter out cases for constant width constant conversion.12344// Don't warn on char array initialization or for non-decimal values.12345static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,12346 SourceLocation CC) {12347 // If initializing from a constant, and the constant starts with '0',12348 // then it is a binary, octal, or hexadecimal. Allow these constants12349 // to fill all the bits, even if there is a sign change.12350 if (auto *IntLit = dyn_cast<IntegerLiteral>(E->IgnoreParenImpCasts())) {12351 const char FirstLiteralCharacter =12352 S.getSourceManager().getCharacterData(IntLit->getBeginLoc())[0];12353 if (FirstLiteralCharacter == '0')12354 return false;12355 }12356 12357 // If the CC location points to a '{', and the type is char, then assume12358 // assume it is an array initialization.12359 if (CC.isValid() && T->isCharType()) {12360 const char FirstContextCharacter =12361 S.getSourceManager().getCharacterData(CC)[0];12362 if (FirstContextCharacter == '{')12363 return false;12364 }12365 12366 return true;12367}12368 12369static const IntegerLiteral *getIntegerLiteral(Expr *E) {12370 const auto *IL = dyn_cast<IntegerLiteral>(E);12371 if (!IL) {12372 if (auto *UO = dyn_cast<UnaryOperator>(E)) {12373 if (UO->getOpcode() == UO_Minus)12374 return dyn_cast<IntegerLiteral>(UO->getSubExpr());12375 }12376 }12377 12378 return IL;12379}12380 12381static void DiagnoseIntInBoolContext(Sema &S, Expr *E) {12382 E = E->IgnoreParenImpCasts();12383 SourceLocation ExprLoc = E->getExprLoc();12384 12385 if (const auto *BO = dyn_cast<BinaryOperator>(E)) {12386 BinaryOperator::Opcode Opc = BO->getOpcode();12387 Expr::EvalResult Result;12388 // Do not diagnose unsigned shifts.12389 if (Opc == BO_Shl) {12390 const auto *LHS = getIntegerLiteral(BO->getLHS());12391 const auto *RHS = getIntegerLiteral(BO->getRHS());12392 if (LHS && LHS->getValue() == 0)12393 S.Diag(ExprLoc, diag::warn_left_shift_always) << 0;12394 else if (!E->isValueDependent() && LHS && RHS &&12395 RHS->getValue().isNonNegative() &&12396 E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects))12397 S.Diag(ExprLoc, diag::warn_left_shift_always)12398 << (Result.Val.getInt() != 0);12399 else if (E->getType()->isSignedIntegerType())12400 S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context)12401 << FixItHint::CreateInsertion(E->getBeginLoc(), "(")12402 << FixItHint::CreateInsertion(S.getLocForEndOfToken(E->getEndLoc()),12403 ") != 0");12404 }12405 }12406 12407 if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {12408 const auto *LHS = getIntegerLiteral(CO->getTrueExpr());12409 const auto *RHS = getIntegerLiteral(CO->getFalseExpr());12410 if (!LHS || !RHS)12411 return;12412 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&12413 (RHS->getValue() == 0 || RHS->getValue() == 1))12414 // Do not diagnose common idioms.12415 return;12416 if (LHS->getValue() != 0 && RHS->getValue() != 0)12417 S.Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);12418 }12419}12420 12421static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source,12422 const Type *Target, Expr *E,12423 QualType T,12424 SourceLocation CC) {12425 assert(Source->isUnicodeCharacterType() && Target->isUnicodeCharacterType() &&12426 Source != Target);12427 12428 // Lone surrogates have a distinct representation in UTF-32.12429 // Converting between UTF-16 and UTF-32 codepoints seems very widespread,12430 // so don't warn on such conversion.12431 if (Source->isChar16Type() && Target->isChar32Type())12432 return;12433 12434 Expr::EvalResult Result;12435 if (E->EvaluateAsInt(Result, S.getASTContext(), Expr::SE_AllowSideEffects,12436 S.isConstantEvaluatedContext())) {12437 llvm::APSInt Value(32);12438 Value = Result.Val.getInt();12439 bool IsASCII = Value <= 0x7F;12440 bool IsBMP = Value <= 0xDFFF || (Value >= 0xE000 && Value <= 0xFFFF);12441 bool ConversionPreservesSemantics =12442 IsASCII || (!Source->isChar8Type() && !Target->isChar8Type() && IsBMP);12443 12444 if (!ConversionPreservesSemantics) {12445 auto IsSingleCodeUnitCP = [](const QualType &T,12446 const llvm::APSInt &Value) {12447 if (T->isChar8Type())12448 return llvm::IsSingleCodeUnitUTF8Codepoint(Value.getExtValue());12449 if (T->isChar16Type())12450 return llvm::IsSingleCodeUnitUTF16Codepoint(Value.getExtValue());12451 assert(T->isChar32Type());12452 return llvm::IsSingleCodeUnitUTF32Codepoint(Value.getExtValue());12453 };12454 12455 S.Diag(CC, diag::warn_impcast_unicode_char_type_constant)12456 << E->getType() << T12457 << IsSingleCodeUnitCP(E->getType().getUnqualifiedType(), Value)12458 << FormatUTFCodeUnitAsCodepoint(Value.getExtValue(), E->getType());12459 }12460 } else {12461 bool LosesPrecision = S.getASTContext().getIntWidth(E->getType()) >12462 S.getASTContext().getIntWidth(T);12463 DiagnoseImpCast(S, E, T, CC,12464 LosesPrecision ? diag::warn_impcast_unicode_precision12465 : diag::warn_impcast_unicode_char_type);12466 }12467}12468 12469bool Sema::DiscardingCFIUncheckedCallee(QualType From, QualType To) const {12470 From = Context.getCanonicalType(From);12471 To = Context.getCanonicalType(To);12472 QualType MaybePointee = From->getPointeeType();12473 if (!MaybePointee.isNull() && MaybePointee->getAs<FunctionType>())12474 From = MaybePointee;12475 MaybePointee = To->getPointeeType();12476 if (!MaybePointee.isNull() && MaybePointee->getAs<FunctionType>())12477 To = MaybePointee;12478 12479 if (const auto *FromFn = From->getAs<FunctionType>()) {12480 if (const auto *ToFn = To->getAs<FunctionType>()) {12481 if (FromFn->getCFIUncheckedCalleeAttr() &&12482 !ToFn->getCFIUncheckedCalleeAttr())12483 return true;12484 }12485 }12486 return false;12487}12488 12489void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,12490 bool *ICContext, bool IsListInit) {12491 if (E->isTypeDependent() || E->isValueDependent()) return;12492 12493 const Type *Source = Context.getCanonicalType(E->getType()).getTypePtr();12494 const Type *Target = Context.getCanonicalType(T).getTypePtr();12495 if (Source == Target) return;12496 if (Target->isDependentType()) return;12497 12498 // If the conversion context location is invalid don't complain. We also12499 // don't want to emit a warning if the issue occurs from the expansion of12500 // a system macro. The problem is that 'getSpellingLoc()' is slow, so we12501 // delay this check as long as possible. Once we detect we are in that12502 // scenario, we just return.12503 if (CC.isInvalid())12504 return;12505 12506 if (Source->isAtomicType())12507 Diag(E->getExprLoc(), diag::warn_atomic_implicit_seq_cst);12508 12509 // Diagnose implicit casts to bool.12510 if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {12511 if (isa<StringLiteral>(E))12512 // Warn on string literal to bool. Checks for string literals in logical12513 // and expressions, for instance, assert(0 && "error here"), are12514 // prevented by a check in AnalyzeImplicitConversions().12515 return DiagnoseImpCast(*this, E, T, CC,12516 diag::warn_impcast_string_literal_to_bool);12517 if (isa<ObjCStringLiteral>(E) || isa<ObjCArrayLiteral>(E) ||12518 isa<ObjCDictionaryLiteral>(E) || isa<ObjCBoxedExpr>(E)) {12519 // This covers the literal expressions that evaluate to Objective-C12520 // objects.12521 return DiagnoseImpCast(*this, E, T, CC,12522 diag::warn_impcast_objective_c_literal_to_bool);12523 }12524 if (Source->isPointerType() || Source->canDecayToPointerType()) {12525 // Warn on pointer to bool conversion that is always true.12526 DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,12527 SourceRange(CC));12528 }12529 }12530 12531 // If the we're converting a constant to an ObjC BOOL on a platform where BOOL12532 // is a typedef for signed char (macOS), then that constant value has to be 112533 // or 0.12534 if (ObjC().isSignedCharBool(T) && Source->isIntegralType(Context)) {12535 Expr::EvalResult Result;12536 if (E->EvaluateAsInt(Result, getASTContext(), Expr::SE_AllowSideEffects)) {12537 if (Result.Val.getInt() != 1 && Result.Val.getInt() != 0) {12538 ObjC().adornBoolConversionDiagWithTernaryFixit(12539 E, Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)12540 << toString(Result.Val.getInt(), 10));12541 }12542 return;12543 }12544 }12545 12546 // Check implicit casts from Objective-C collection literals to specialized12547 // collection types, e.g., NSArray<NSString *> *.12548 if (auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))12549 ObjC().checkArrayLiteral(QualType(Target, 0), ArrayLiteral);12550 else if (auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))12551 ObjC().checkDictionaryLiteral(QualType(Target, 0), DictionaryLiteral);12552 12553 // Strip vector types.12554 if (isa<VectorType>(Source)) {12555 if (Target->isSveVLSBuiltinType() &&12556 (ARM().areCompatibleSveTypes(QualType(Target, 0),12557 QualType(Source, 0)) ||12558 ARM().areLaxCompatibleSveTypes(QualType(Target, 0),12559 QualType(Source, 0))))12560 return;12561 12562 if (Target->isRVVVLSBuiltinType() &&12563 (Context.areCompatibleRVVTypes(QualType(Target, 0),12564 QualType(Source, 0)) ||12565 Context.areLaxCompatibleRVVTypes(QualType(Target, 0),12566 QualType(Source, 0))))12567 return;12568 12569 if (!isa<VectorType>(Target)) {12570 if (SourceMgr.isInSystemMacro(CC))12571 return;12572 return DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_vector_scalar);12573 } else if (getLangOpts().HLSL &&12574 Target->castAs<VectorType>()->getNumElements() <12575 Source->castAs<VectorType>()->getNumElements()) {12576 // Diagnose vector truncation but don't return. We may also want to12577 // diagnose an element conversion.12578 DiagnoseImpCast(*this, E, T, CC,12579 diag::warn_hlsl_impcast_vector_truncation);12580 }12581 12582 // If the vector cast is cast between two vectors of the same size, it is12583 // a bitcast, not a conversion, except under HLSL where it is a conversion.12584 if (!getLangOpts().HLSL &&12585 Context.getTypeSize(Source) == Context.getTypeSize(Target))12586 return;12587 12588 Source = cast<VectorType>(Source)->getElementType().getTypePtr();12589 Target = cast<VectorType>(Target)->getElementType().getTypePtr();12590 }12591 if (auto VecTy = dyn_cast<VectorType>(Target))12592 Target = VecTy->getElementType().getTypePtr();12593 12594 // Strip complex types.12595 if (isa<ComplexType>(Source)) {12596 if (!isa<ComplexType>(Target)) {12597 if (SourceMgr.isInSystemMacro(CC) || Target->isBooleanType())12598 return;12599 12600 return DiagnoseImpCast(*this, E, T, CC,12601 getLangOpts().CPlusPlus12602 ? diag::err_impcast_complex_scalar12603 : diag::warn_impcast_complex_scalar);12604 }12605 12606 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();12607 Target = cast<ComplexType>(Target)->getElementType().getTypePtr();12608 }12609 12610 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);12611 const BuiltinType *TargetBT = dyn_cast<BuiltinType>(Target);12612 12613 // Strip SVE vector types12614 if (SourceBT && SourceBT->isSveVLSBuiltinType()) {12615 // Need the original target type for vector type checks12616 const Type *OriginalTarget = Context.getCanonicalType(T).getTypePtr();12617 // Handle conversion from scalable to fixed when msve-vector-bits is12618 // specified12619 if (ARM().areCompatibleSveTypes(QualType(OriginalTarget, 0),12620 QualType(Source, 0)) ||12621 ARM().areLaxCompatibleSveTypes(QualType(OriginalTarget, 0),12622 QualType(Source, 0)))12623 return;12624 12625 // If the vector cast is cast between two vectors of the same size, it is12626 // a bitcast, not a conversion.12627 if (Context.getTypeSize(Source) == Context.getTypeSize(Target))12628 return;12629 12630 Source = SourceBT->getSveEltType(Context).getTypePtr();12631 }12632 12633 if (TargetBT && TargetBT->isSveVLSBuiltinType())12634 Target = TargetBT->getSveEltType(Context).getTypePtr();12635 12636 // If the source is floating point...12637 if (SourceBT && SourceBT->isFloatingPoint()) {12638 // ...and the target is floating point...12639 if (TargetBT && TargetBT->isFloatingPoint()) {12640 // ...then warn if we're dropping FP rank.12641 12642 int Order = getASTContext().getFloatingTypeSemanticOrder(12643 QualType(SourceBT, 0), QualType(TargetBT, 0));12644 if (Order > 0) {12645 // Don't warn about float constants that are precisely12646 // representable in the target type.12647 Expr::EvalResult result;12648 if (E->EvaluateAsRValue(result, Context)) {12649 // Value might be a float, a float vector, or a float complex.12650 if (IsSameFloatAfterCast(12651 result.Val,12652 Context.getFloatTypeSemantics(QualType(TargetBT, 0)),12653 Context.getFloatTypeSemantics(QualType(SourceBT, 0))))12654 return;12655 }12656 12657 if (SourceMgr.isInSystemMacro(CC))12658 return;12659 12660 DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_float_precision);12661 }12662 // ... or possibly if we're increasing rank, too12663 else if (Order < 0) {12664 if (SourceMgr.isInSystemMacro(CC))12665 return;12666 12667 DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_double_promotion);12668 }12669 return;12670 }12671 12672 // If the target is integral, always warn.12673 if (TargetBT && TargetBT->isInteger()) {12674 if (SourceMgr.isInSystemMacro(CC))12675 return;12676 12677 DiagnoseFloatingImpCast(*this, E, T, CC);12678 }12679 12680 // Detect the case where a call result is converted from floating-point to12681 // to bool, and the final argument to the call is converted from bool, to12682 // discover this typo:12683 //12684 // bool b = fabs(x < 1.0); // should be "bool b = fabs(x) < 1.0;"12685 //12686 // FIXME: This is an incredibly special case; is there some more general12687 // way to detect this class of misplaced-parentheses bug?12688 if (Target->isBooleanType() && isa<CallExpr>(E)) {12689 // Check last argument of function call to see if it is an12690 // implicit cast from a type matching the type the result12691 // is being cast to.12692 CallExpr *CEx = cast<CallExpr>(E);12693 if (unsigned NumArgs = CEx->getNumArgs()) {12694 Expr *LastA = CEx->getArg(NumArgs - 1);12695 Expr *InnerE = LastA->IgnoreParenImpCasts();12696 if (isa<ImplicitCastExpr>(LastA) &&12697 InnerE->getType()->isBooleanType()) {12698 // Warn on this floating-point to bool conversion12699 DiagnoseImpCast(*this, E, T, CC,12700 diag::warn_impcast_floating_point_to_bool);12701 }12702 }12703 }12704 return;12705 }12706 12707 // Valid casts involving fixed point types should be accounted for here.12708 if (Source->isFixedPointType()) {12709 if (Target->isUnsaturatedFixedPointType()) {12710 Expr::EvalResult Result;12711 if (E->EvaluateAsFixedPoint(Result, Context, Expr::SE_AllowSideEffects,12712 isConstantEvaluatedContext())) {12713 llvm::APFixedPoint Value = Result.Val.getFixedPoint();12714 llvm::APFixedPoint MaxVal = Context.getFixedPointMax(T);12715 llvm::APFixedPoint MinVal = Context.getFixedPointMin(T);12716 if (Value > MaxVal || Value < MinVal) {12717 DiagRuntimeBehavior(E->getExprLoc(), E,12718 PDiag(diag::warn_impcast_fixed_point_range)12719 << Value.toString() << T12720 << E->getSourceRange()12721 << clang::SourceRange(CC));12722 return;12723 }12724 }12725 } else if (Target->isIntegerType()) {12726 Expr::EvalResult Result;12727 if (!isConstantEvaluatedContext() &&12728 E->EvaluateAsFixedPoint(Result, Context, Expr::SE_AllowSideEffects)) {12729 llvm::APFixedPoint FXResult = Result.Val.getFixedPoint();12730 12731 bool Overflowed;12732 llvm::APSInt IntResult = FXResult.convertToInt(12733 Context.getIntWidth(T), Target->isSignedIntegerOrEnumerationType(),12734 &Overflowed);12735 12736 if (Overflowed) {12737 DiagRuntimeBehavior(E->getExprLoc(), E,12738 PDiag(diag::warn_impcast_fixed_point_range)12739 << FXResult.toString() << T12740 << E->getSourceRange()12741 << clang::SourceRange(CC));12742 return;12743 }12744 }12745 }12746 } else if (Target->isUnsaturatedFixedPointType()) {12747 if (Source->isIntegerType()) {12748 Expr::EvalResult Result;12749 if (!isConstantEvaluatedContext() &&12750 E->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects)) {12751 llvm::APSInt Value = Result.Val.getInt();12752 12753 bool Overflowed;12754 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(12755 Value, Context.getFixedPointSemantics(T), &Overflowed);12756 12757 if (Overflowed) {12758 DiagRuntimeBehavior(E->getExprLoc(), E,12759 PDiag(diag::warn_impcast_fixed_point_range)12760 << toString(Value, /*Radix=*/10) << T12761 << E->getSourceRange()12762 << clang::SourceRange(CC));12763 return;12764 }12765 }12766 }12767 }12768 12769 // If we are casting an integer type to a floating point type without12770 // initialization-list syntax, we might lose accuracy if the floating12771 // point type has a narrower significand than the integer type.12772 if (SourceBT && TargetBT && SourceBT->isIntegerType() &&12773 TargetBT->isFloatingType() && !IsListInit) {12774 // Determine the number of precision bits in the source integer type.12775 std::optional<IntRange> SourceRange =12776 TryGetExprRange(Context, E, isConstantEvaluatedContext(),12777 /*Approximate=*/true);12778 if (!SourceRange)12779 return;12780 unsigned int SourcePrecision = SourceRange->Width;12781 12782 // Determine the number of precision bits in the12783 // target floating point type.12784 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(12785 Context.getFloatTypeSemantics(QualType(TargetBT, 0)));12786 12787 if (SourcePrecision > 0 && TargetPrecision > 0 &&12788 SourcePrecision > TargetPrecision) {12789 12790 if (std::optional<llvm::APSInt> SourceInt =12791 E->getIntegerConstantExpr(Context)) {12792 // If the source integer is a constant, convert it to the target12793 // floating point type. Issue a warning if the value changes12794 // during the whole conversion.12795 llvm::APFloat TargetFloatValue(12796 Context.getFloatTypeSemantics(QualType(TargetBT, 0)));12797 llvm::APFloat::opStatus ConversionStatus =12798 TargetFloatValue.convertFromAPInt(12799 *SourceInt, SourceBT->isSignedInteger(),12800 llvm::APFloat::rmNearestTiesToEven);12801 12802 if (ConversionStatus != llvm::APFloat::opOK) {12803 SmallString<32> PrettySourceValue;12804 SourceInt->toString(PrettySourceValue, 10);12805 SmallString<32> PrettyTargetValue;12806 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);12807 12808 DiagRuntimeBehavior(12809 E->getExprLoc(), E,12810 PDiag(diag::warn_impcast_integer_float_precision_constant)12811 << PrettySourceValue << PrettyTargetValue << E->getType() << T12812 << E->getSourceRange() << clang::SourceRange(CC));12813 }12814 } else {12815 // Otherwise, the implicit conversion may lose precision.12816 DiagnoseImpCast(*this, E, T, CC,12817 diag::warn_impcast_integer_float_precision);12818 }12819 }12820 }12821 12822 DiagnoseNullConversion(*this, E, T, CC);12823 12824 DiscardMisalignedMemberAddress(Target, E);12825 12826 if (Source->isUnicodeCharacterType() && Target->isUnicodeCharacterType()) {12827 DiagnoseMixedUnicodeImplicitConversion(*this, Source, Target, E, T, CC);12828 return;12829 }12830 12831 if (Target->isBooleanType())12832 DiagnoseIntInBoolContext(*this, E);12833 12834 if (DiscardingCFIUncheckedCallee(QualType(Source, 0), QualType(Target, 0))) {12835 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)12836 << QualType(Source, 0) << QualType(Target, 0);12837 }12838 12839 if (!Source->isIntegerType() || !Target->isIntegerType())12840 return;12841 12842 // TODO: remove this early return once the false positives for constant->bool12843 // in templates, macros, etc, are reduced or removed.12844 if (Target->isSpecificBuiltinType(BuiltinType::Bool))12845 return;12846 12847 if (ObjC().isSignedCharBool(T) && !Source->isCharType() &&12848 !E->isKnownToHaveBooleanValue(/*Semantic=*/false)) {12849 return ObjC().adornBoolConversionDiagWithTernaryFixit(12850 E, Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)12851 << E->getType());12852 }12853 std::optional<IntRange> LikelySourceRange = TryGetExprRange(12854 Context, E, isConstantEvaluatedContext(), /*Approximate=*/true);12855 if (!LikelySourceRange)12856 return;12857 12858 IntRange SourceTypeRange =12859 IntRange::forTargetOfCanonicalType(Context, Source);12860 IntRange TargetRange = IntRange::forTargetOfCanonicalType(Context, Target);12861 12862 if (LikelySourceRange->Width > TargetRange.Width) {12863 // If the source is a constant, use a default-on diagnostic.12864 // TODO: this should happen for bitfield stores, too.12865 Expr::EvalResult Result;12866 if (E->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects,12867 isConstantEvaluatedContext())) {12868 llvm::APSInt Value(32);12869 Value = Result.Val.getInt();12870 12871 if (SourceMgr.isInSystemMacro(CC))12872 return;12873 12874 std::string PrettySourceValue = toString(Value, 10);12875 std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);12876 12877 DiagRuntimeBehavior(E->getExprLoc(), E,12878 PDiag(diag::warn_impcast_integer_precision_constant)12879 << PrettySourceValue << PrettyTargetValue12880 << E->getType() << T << E->getSourceRange()12881 << SourceRange(CC));12882 return;12883 }12884 12885 // People want to build with -Wshorten-64-to-32 and not -Wconversion.12886 if (SourceMgr.isInSystemMacro(CC))12887 return;12888 12889 if (const auto *UO = dyn_cast<UnaryOperator>(E)) {12890 if (UO->getOpcode() == UO_Minus)12891 return DiagnoseImpCast(12892 *this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);12893 }12894 12895 if (TargetRange.Width == 32 && Context.getIntWidth(E->getType()) == 64)12896 return DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_integer_64_32,12897 /* pruneControlFlow */ true);12898 return DiagnoseImpCast(*this, E, T, CC,12899 diag::warn_impcast_integer_precision);12900 }12901 12902 if (TargetRange.Width > SourceTypeRange.Width) {12903 if (auto *UO = dyn_cast<UnaryOperator>(E))12904 if (UO->getOpcode() == UO_Minus)12905 if (Source->isUnsignedIntegerType()) {12906 if (Target->isUnsignedIntegerType())12907 return DiagnoseImpCast(*this, E, T, CC,12908 diag::warn_impcast_high_order_zero_bits);12909 if (Target->isSignedIntegerType())12910 return DiagnoseImpCast(*this, E, T, CC,12911 diag::warn_impcast_nonnegative_result);12912 }12913 }12914 12915 if (TargetRange.Width == LikelySourceRange->Width &&12916 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&12917 Source->isSignedIntegerType()) {12918 // Warn when doing a signed to signed conversion, warn if the positive12919 // source value is exactly the width of the target type, which will12920 // cause a negative value to be stored.12921 12922 Expr::EvalResult Result;12923 if (E->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects) &&12924 !SourceMgr.isInSystemMacro(CC)) {12925 llvm::APSInt Value = Result.Val.getInt();12926 if (isSameWidthConstantConversion(*this, E, T, CC)) {12927 std::string PrettySourceValue = toString(Value, 10);12928 std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);12929 12930 Diag(E->getExprLoc(),12931 PDiag(diag::warn_impcast_integer_precision_constant)12932 << PrettySourceValue << PrettyTargetValue << E->getType() << T12933 << E->getSourceRange() << SourceRange(CC));12934 return;12935 }12936 }12937 12938 // Fall through for non-constants to give a sign conversion warning.12939 }12940 12941 if ((!isa<EnumType>(Target) || !isa<EnumType>(Source)) &&12942 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||12943 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&12944 LikelySourceRange->Width == TargetRange.Width))) {12945 if (SourceMgr.isInSystemMacro(CC))12946 return;12947 12948 if (SourceBT && SourceBT->isInteger() && TargetBT &&12949 TargetBT->isInteger() &&12950 Source->isSignedIntegerType() == Target->isSignedIntegerType()) {12951 return;12952 }12953 12954 unsigned DiagID = diag::warn_impcast_integer_sign;12955 12956 // Traditionally, gcc has warned about this under -Wsign-compare.12957 // We also want to warn about it in -Wconversion.12958 // So if -Wconversion is off, use a completely identical diagnostic12959 // in the sign-compare group.12960 // The conditional-checking code will12961 if (ICContext) {12962 DiagID = diag::warn_impcast_integer_sign_conditional;12963 *ICContext = true;12964 }12965 12966 DiagnoseImpCast(*this, E, T, CC, DiagID);12967 }12968 12969 // If we're implicitly converting from an integer into an enumeration, that12970 // is valid in C but invalid in C++.12971 QualType SourceType = E->getEnumCoercedType(Context);12972 const BuiltinType *CoercedSourceBT = SourceType->getAs<BuiltinType>();12973 if (CoercedSourceBT && CoercedSourceBT->isInteger() && isa<EnumType>(Target))12974 return DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_int_to_enum);12975 12976 // Diagnose conversions between different enumeration types.12977 // In C, we pretend that the type of an EnumConstantDecl is its enumeration12978 // type, to give us better diagnostics.12979 Source = Context.getCanonicalType(SourceType).getTypePtr();12980 12981 if (const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())12982 if (const EnumType *TargetEnum = Target->getAsCanonical<EnumType>())12983 if (SourceEnum->getDecl()->hasNameForLinkage() &&12984 TargetEnum->getDecl()->hasNameForLinkage() &&12985 SourceEnum != TargetEnum) {12986 if (SourceMgr.isInSystemMacro(CC))12987 return;12988 12989 return DiagnoseImpCast(*this, E, SourceType, T, CC,12990 diag::warn_impcast_different_enum_types);12991 }12992}12993 12994static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E,12995 SourceLocation CC, QualType T);12996 12997static void CheckConditionalOperand(Sema &S, Expr *E, QualType T,12998 SourceLocation CC, bool &ICContext) {12999 E = E->IgnoreParenImpCasts();13000 // Diagnose incomplete type for second or third operand in C.13001 if (!S.getLangOpts().CPlusPlus && E->getType()->isRecordType())13002 S.RequireCompleteExprType(E, diag::err_incomplete_type);13003 13004 if (auto *CO = dyn_cast<AbstractConditionalOperator>(E))13005 return CheckConditionalOperator(S, CO, CC, T);13006 13007 AnalyzeImplicitConversions(S, E, CC);13008 if (E->getType() != T)13009 return S.CheckImplicitConversion(E, T, CC, &ICContext);13010}13011 13012static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E,13013 SourceLocation CC, QualType T) {13014 AnalyzeImplicitConversions(S, E->getCond(), E->getQuestionLoc());13015 13016 Expr *TrueExpr = E->getTrueExpr();13017 if (auto *BCO = dyn_cast<BinaryConditionalOperator>(E))13018 TrueExpr = BCO->getCommon();13019 13020 bool Suspicious = false;13021 CheckConditionalOperand(S, TrueExpr, T, CC, Suspicious);13022 CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious);13023 13024 if (T->isBooleanType())13025 DiagnoseIntInBoolContext(S, E);13026 13027 // If -Wconversion would have warned about either of the candidates13028 // for a signedness conversion to the context type...13029 if (!Suspicious) return;13030 13031 // ...but it's currently ignored...13032 if (!S.Diags.isIgnored(diag::warn_impcast_integer_sign_conditional, CC))13033 return;13034 13035 // ...then check whether it would have warned about either of the13036 // candidates for a signedness conversion to the condition type.13037 if (E->getType() == T) return;13038 13039 Suspicious = false;13040 S.CheckImplicitConversion(TrueExpr->IgnoreParenImpCasts(), E->getType(), CC,13041 &Suspicious);13042 if (!Suspicious)13043 S.CheckImplicitConversion(E->getFalseExpr()->IgnoreParenImpCasts(),13044 E->getType(), CC, &Suspicious);13045}13046 13047/// Check conversion of given expression to boolean.13048/// Input argument E is a logical expression.13049static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {13050 // Run the bool-like conversion checks only for C since there bools are13051 // still not used as the return type from "boolean" operators or as the input13052 // type for conditional operators.13053 if (S.getLangOpts().CPlusPlus)13054 return;13055 if (E->IgnoreParenImpCasts()->getType()->isAtomicType())13056 return;13057 S.CheckImplicitConversion(E->IgnoreParenImpCasts(), S.Context.BoolTy, CC);13058}13059 13060namespace {13061struct AnalyzeImplicitConversionsWorkItem {13062 Expr *E;13063 SourceLocation CC;13064 bool IsListInit;13065};13066}13067 13068static void CheckCommaOperand(13069 Sema &S, Expr *E, QualType T, SourceLocation CC,13070 bool ExtraCheckForImplicitConversion,13071 llvm::SmallVectorImpl<AnalyzeImplicitConversionsWorkItem> &WorkList) {13072 E = E->IgnoreParenImpCasts();13073 WorkList.push_back({E, CC, false});13074 13075 if (ExtraCheckForImplicitConversion && E->getType() != T)13076 S.CheckImplicitConversion(E, T, CC);13077}13078 13079/// Data recursive variant of AnalyzeImplicitConversions. Subexpressions13080/// that should be visited are added to WorkList.13081static void AnalyzeImplicitConversions(13082 Sema &S, AnalyzeImplicitConversionsWorkItem Item,13083 llvm::SmallVectorImpl<AnalyzeImplicitConversionsWorkItem> &WorkList) {13084 Expr *OrigE = Item.E;13085 SourceLocation CC = Item.CC;13086 13087 QualType T = OrigE->getType();13088 Expr *E = OrigE->IgnoreParenImpCasts();13089 13090 // Propagate whether we are in a C++ list initialization expression.13091 // If so, we do not issue warnings for implicit int-float conversion13092 // precision loss, because C++11 narrowing already handles it.13093 //13094 // HLSL's initialization lists are special, so they shouldn't observe the C++13095 // behavior here.13096 bool IsListInit =13097 Item.IsListInit || (isa<InitListExpr>(OrigE) &&13098 S.getLangOpts().CPlusPlus && !S.getLangOpts().HLSL);13099 13100 if (E->isTypeDependent() || E->isValueDependent())13101 return;13102 13103 Expr *SourceExpr = E;13104 // Examine, but don't traverse into the source expression of an13105 // OpaqueValueExpr, since it may have multiple parents and we don't want to13106 // emit duplicate diagnostics. Its fine to examine the form or attempt to13107 // evaluate it in the context of checking the specific conversion to T though.13108 if (auto *OVE = dyn_cast<OpaqueValueExpr>(E))13109 if (auto *Src = OVE->getSourceExpr())13110 SourceExpr = Src;13111 13112 if (const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))13113 if (UO->getOpcode() == UO_Not &&13114 UO->getSubExpr()->isKnownToHaveBooleanValue())13115 S.Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)13116 << OrigE->getSourceRange() << T->isBooleanType()13117 << FixItHint::CreateReplacement(UO->getBeginLoc(), "!");13118 13119 if (auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {13120 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&13121 BO->getLHS()->isKnownToHaveBooleanValue() &&13122 BO->getRHS()->isKnownToHaveBooleanValue() &&13123 BO->getLHS()->HasSideEffects(S.Context) &&13124 BO->getRHS()->HasSideEffects(S.Context)) {13125 SourceManager &SM = S.getSourceManager();13126 const LangOptions &LO = S.getLangOpts();13127 SourceLocation BLoc = BO->getOperatorLoc();13128 SourceLocation ELoc = Lexer::getLocForEndOfToken(BLoc, 0, SM, LO);13129 StringRef SR = clang::Lexer::getSourceText(13130 clang::CharSourceRange::getTokenRange(BLoc, ELoc), SM, LO);13131 // To reduce false positives, only issue the diagnostic if the operator13132 // is explicitly spelled as a punctuator. This suppresses the diagnostic13133 // when using 'bitand' or 'bitor' either as keywords in C++ or as macros13134 // in C, along with other macro spellings the user might invent.13135 if (SR.str() == "&" || SR.str() == "|") {13136 13137 S.Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)13138 << (BO->getOpcode() == BO_And ? "&" : "|")13139 << OrigE->getSourceRange()13140 << FixItHint::CreateReplacement(13141 BO->getOperatorLoc(),13142 (BO->getOpcode() == BO_And ? "&&" : "||"));13143 S.Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);13144 }13145 } else if (BO->isCommaOp() && !S.getLangOpts().CPlusPlus) {13146 /// Analyze the given comma operator. The basic idea behind the analysis13147 /// is to analyze the left and right operands slightly differently. The13148 /// left operand needs to check whether the operand itself has an implicit13149 /// conversion, but not whether the left operand induces an implicit13150 /// conversion for the entire comma expression itself. This is similar to13151 /// how CheckConditionalOperand behaves; it's as-if the correct operand13152 /// were directly used for the implicit conversion check.13153 CheckCommaOperand(S, BO->getLHS(), T, BO->getOperatorLoc(),13154 /*ExtraCheckForImplicitConversion=*/false, WorkList);13155 CheckCommaOperand(S, BO->getRHS(), T, BO->getOperatorLoc(),13156 /*ExtraCheckForImplicitConversion=*/true, WorkList);13157 return;13158 }13159 }13160 13161 // For conditional operators, we analyze the arguments as if they13162 // were being fed directly into the output.13163 if (auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {13164 CheckConditionalOperator(S, CO, CC, T);13165 return;13166 }13167 13168 // Check implicit argument conversions for function calls.13169 if (const auto *Call = dyn_cast<CallExpr>(SourceExpr))13170 CheckImplicitArgumentConversions(S, Call, CC);13171 13172 // Go ahead and check any implicit conversions we might have skipped.13173 // The non-canonical typecheck is just an optimization;13174 // CheckImplicitConversion will filter out dead implicit conversions.13175 if (SourceExpr->getType() != T)13176 S.CheckImplicitConversion(SourceExpr, T, CC, nullptr, IsListInit);13177 13178 // Now continue drilling into this expression.13179 13180 if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {13181 // The bound subexpressions in a PseudoObjectExpr are not reachable13182 // as transitive children.13183 // FIXME: Use a more uniform representation for this.13184 for (auto *SE : POE->semantics())13185 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SE))13186 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});13187 }13188 13189 // Skip past explicit casts.13190 if (auto *CE = dyn_cast<ExplicitCastExpr>(E)) {13191 E = CE->getSubExpr();13192 // In the special case of a C++ function-style cast with braces,13193 // CXXFunctionalCastExpr has an InitListExpr as direct child with a single13194 // initializer. This InitListExpr basically belongs to the cast itself, so13195 // we skip it too. Specifically this is needed to silence -Wdouble-promotion13196 if (isa<CXXFunctionalCastExpr>(CE)) {13197 if (auto *InitListE = dyn_cast<InitListExpr>(E)) {13198 if (InitListE->getNumInits() == 1) {13199 E = InitListE->getInit(0);13200 }13201 }13202 }13203 E = E->IgnoreParenImpCasts();13204 if (!CE->getType()->isVoidType() && E->getType()->isAtomicType())13205 S.Diag(E->getBeginLoc(), diag::warn_atomic_implicit_seq_cst);13206 WorkList.push_back({E, CC, IsListInit});13207 return;13208 }13209 13210 if (auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {13211 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});13212 // The base expression is only used to initialize the parameter for13213 // arguments to `inout` parameters, so we only traverse down the base13214 // expression for `inout` cases.13215 if (OutArgE->isInOut())13216 WorkList.push_back(13217 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});13218 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});13219 return;13220 }13221 13222 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {13223 // Do a somewhat different check with comparison operators.13224 if (BO->isComparisonOp())13225 return AnalyzeComparison(S, BO);13226 13227 // And with simple assignments.13228 if (BO->getOpcode() == BO_Assign)13229 return AnalyzeAssignment(S, BO);13230 // And with compound assignments.13231 if (BO->isAssignmentOp())13232 return AnalyzeCompoundAssignment(S, BO);13233 }13234 13235 // These break the otherwise-useful invariant below. Fortunately,13236 // we don't really need to recurse into them, because any internal13237 // expressions should have been analyzed already when they were13238 // built into statements.13239 if (isa<StmtExpr>(E)) return;13240 13241 // Don't descend into unevaluated contexts.13242 if (isa<UnaryExprOrTypeTraitExpr>(E)) return;13243 13244 // Now just recurse over the expression's children.13245 CC = E->getExprLoc();13246 BinaryOperator *BO = dyn_cast<BinaryOperator>(E);13247 bool IsLogicalAndOperator = BO && BO->getOpcode() == BO_LAnd;13248 for (Stmt *SubStmt : E->children()) {13249 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);13250 if (!ChildExpr)13251 continue;13252 13253 if (auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))13254 if (ChildExpr == CSE->getOperand())13255 // Do not recurse over a CoroutineSuspendExpr's operand.13256 // The operand is also a subexpression of getCommonExpr(), and13257 // recursing into it directly would produce duplicate diagnostics.13258 continue;13259 13260 if (IsLogicalAndOperator &&13261 isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts()))13262 // Ignore checking string literals that are in logical and operators.13263 // This is a common pattern for asserts.13264 continue;13265 WorkList.push_back({ChildExpr, CC, IsListInit});13266 }13267 13268 if (BO && BO->isLogicalOp()) {13269 Expr *SubExpr = BO->getLHS()->IgnoreParenImpCasts();13270 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))13271 ::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc());13272 13273 SubExpr = BO->getRHS()->IgnoreParenImpCasts();13274 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))13275 ::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc());13276 }13277 13278 if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {13279 if (U->getOpcode() == UO_LNot) {13280 ::CheckBoolLikeConversion(S, U->getSubExpr(), CC);13281 } else if (U->getOpcode() != UO_AddrOf) {13282 if (U->getSubExpr()->getType()->isAtomicType())13283 S.Diag(U->getSubExpr()->getBeginLoc(),13284 diag::warn_atomic_implicit_seq_cst);13285 }13286 }13287}13288 13289/// AnalyzeImplicitConversions - Find and report any interesting13290/// implicit conversions in the given expression. There are a couple13291/// of competing diagnostics here, -Wconversion and -Wsign-compare.13292static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC,13293 bool IsListInit/*= false*/) {13294 llvm::SmallVector<AnalyzeImplicitConversionsWorkItem, 16> WorkList;13295 WorkList.push_back({OrigE, CC, IsListInit});13296 while (!WorkList.empty())13297 AnalyzeImplicitConversions(S, WorkList.pop_back_val(), WorkList);13298}13299 13300// Helper function for Sema::DiagnoseAlwaysNonNullPointer.13301// Returns true when emitting a warning about taking the address of a reference.13302static bool CheckForReference(Sema &SemaRef, const Expr *E,13303 const PartialDiagnostic &PD) {13304 E = E->IgnoreParenImpCasts();13305 13306 const FunctionDecl *FD = nullptr;13307 13308 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {13309 if (!DRE->getDecl()->getType()->isReferenceType())13310 return false;13311 } else if (const MemberExpr *M = dyn_cast<MemberExpr>(E)) {13312 if (!M->getMemberDecl()->getType()->isReferenceType())13313 return false;13314 } else if (const CallExpr *Call = dyn_cast<CallExpr>(E)) {13315 if (!Call->getCallReturnType(SemaRef.Context)->isReferenceType())13316 return false;13317 FD = Call->getDirectCallee();13318 } else {13319 return false;13320 }13321 13322 SemaRef.Diag(E->getExprLoc(), PD);13323 13324 // If possible, point to location of function.13325 if (FD) {13326 SemaRef.Diag(FD->getLocation(), diag::note_reference_is_return_value) << FD;13327 }13328 13329 return true;13330}13331 13332// Returns true if the SourceLocation is expanded from any macro body.13333// Returns false if the SourceLocation is invalid, is from not in a macro13334// expansion, or is from expanded from a top-level macro argument.13335static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc) {13336 if (Loc.isInvalid())13337 return false;13338 13339 while (Loc.isMacroID()) {13340 if (SM.isMacroBodyExpansion(Loc))13341 return true;13342 Loc = SM.getImmediateMacroCallerLoc(Loc);13343 }13344 13345 return false;13346}13347 13348void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,13349 Expr::NullPointerConstantKind NullKind,13350 bool IsEqual, SourceRange Range) {13351 if (!E)13352 return;13353 13354 // Don't warn inside macros.13355 if (E->getExprLoc().isMacroID()) {13356 const SourceManager &SM = getSourceManager();13357 if (IsInAnyMacroBody(SM, E->getExprLoc()) ||13358 IsInAnyMacroBody(SM, Range.getBegin()))13359 return;13360 }13361 E = E->IgnoreImpCasts();13362 13363 const bool IsCompare = NullKind != Expr::NPCK_NotNull;13364 13365 if (isa<CXXThisExpr>(E)) {13366 unsigned DiagID = IsCompare ? diag::warn_this_null_compare13367 : diag::warn_this_bool_conversion;13368 Diag(E->getExprLoc(), DiagID) << E->getSourceRange() << Range << IsEqual;13369 return;13370 }13371 13372 bool IsAddressOf = false;13373 13374 if (auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) {13375 if (UO->getOpcode() != UO_AddrOf)13376 return;13377 IsAddressOf = true;13378 E = UO->getSubExpr();13379 }13380 13381 if (IsAddressOf) {13382 unsigned DiagID = IsCompare13383 ? diag::warn_address_of_reference_null_compare13384 : diag::warn_address_of_reference_bool_conversion;13385 PartialDiagnostic PD = PDiag(DiagID) << E->getSourceRange() << Range13386 << IsEqual;13387 if (CheckForReference(*this, E, PD)) {13388 return;13389 }13390 }13391 13392 auto ComplainAboutNonnullParamOrCall = [&](const Attr *NonnullAttr) {13393 bool IsParam = isa<NonNullAttr>(NonnullAttr);13394 std::string Str;13395 llvm::raw_string_ostream S(Str);13396 E->printPretty(S, nullptr, getPrintingPolicy());13397 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare13398 : diag::warn_cast_nonnull_to_bool;13399 Diag(E->getExprLoc(), DiagID) << IsParam << S.str()13400 << E->getSourceRange() << Range << IsEqual;13401 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;13402 };13403 13404 // If we have a CallExpr that is tagged with returns_nonnull, we can complain.13405 if (auto *Call = dyn_cast<CallExpr>(E->IgnoreParenImpCasts())) {13406 if (auto *Callee = Call->getDirectCallee()) {13407 if (const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {13408 ComplainAboutNonnullParamOrCall(A);13409 return;13410 }13411 }13412 }13413 13414 // Complain if we are converting a lambda expression to a boolean value13415 // outside of instantiation.13416 if (!inTemplateInstantiation()) {13417 if (const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {13418 if (const auto *MRecordDecl = MCallExpr->getRecordDecl();13419 MRecordDecl && MRecordDecl->isLambda()) {13420 Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)13421 << /*LambdaPointerConversionOperatorType=*/313422 << MRecordDecl->getSourceRange() << Range << IsEqual;13423 return;13424 }13425 }13426 }13427 13428 // Expect to find a single Decl. Skip anything more complicated.13429 ValueDecl *D = nullptr;13430 if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {13431 D = R->getDecl();13432 } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {13433 D = M->getMemberDecl();13434 }13435 13436 // Weak Decls can be null.13437 if (!D || D->isWeak())13438 return;13439 13440 // Check for parameter decl with nonnull attribute13441 if (const auto* PV = dyn_cast<ParmVarDecl>(D)) {13442 if (getCurFunction() &&13443 !getCurFunction()->ModifiedNonNullParams.count(PV)) {13444 if (const Attr *A = PV->getAttr<NonNullAttr>()) {13445 ComplainAboutNonnullParamOrCall(A);13446 return;13447 }13448 13449 if (const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {13450 // Skip function template not specialized yet.13451 if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)13452 return;13453 auto ParamIter = llvm::find(FD->parameters(), PV);13454 assert(ParamIter != FD->param_end());13455 unsigned ParamNo = std::distance(FD->param_begin(), ParamIter);13456 13457 for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) {13458 if (!NonNull->args_size()) {13459 ComplainAboutNonnullParamOrCall(NonNull);13460 return;13461 }13462 13463 for (const ParamIdx &ArgNo : NonNull->args()) {13464 if (ArgNo.getASTIndex() == ParamNo) {13465 ComplainAboutNonnullParamOrCall(NonNull);13466 return;13467 }13468 }13469 }13470 }13471 }13472 }13473 13474 QualType T = D->getType();13475 const bool IsArray = T->isArrayType();13476 const bool IsFunction = T->isFunctionType();13477 13478 // Address of function is used to silence the function warning.13479 if (IsAddressOf && IsFunction) {13480 return;13481 }13482 13483 // Found nothing.13484 if (!IsAddressOf && !IsFunction && !IsArray)13485 return;13486 13487 // Pretty print the expression for the diagnostic.13488 std::string Str;13489 llvm::raw_string_ostream S(Str);13490 E->printPretty(S, nullptr, getPrintingPolicy());13491 13492 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare13493 : diag::warn_impcast_pointer_to_bool;13494 enum {13495 AddressOf,13496 FunctionPointer,13497 ArrayPointer13498 } DiagType;13499 if (IsAddressOf)13500 DiagType = AddressOf;13501 else if (IsFunction)13502 DiagType = FunctionPointer;13503 else if (IsArray)13504 DiagType = ArrayPointer;13505 else13506 llvm_unreachable("Could not determine diagnostic.");13507 Diag(E->getExprLoc(), DiagID) << DiagType << S.str() << E->getSourceRange()13508 << Range << IsEqual;13509 13510 if (!IsFunction)13511 return;13512 13513 // Suggest '&' to silence the function warning.13514 Diag(E->getExprLoc(), diag::note_function_warning_silence)13515 << FixItHint::CreateInsertion(E->getBeginLoc(), "&");13516 13517 // Check to see if '()' fixit should be emitted.13518 QualType ReturnType;13519 UnresolvedSet<4> NonTemplateOverloads;13520 tryExprAsCall(*E, ReturnType, NonTemplateOverloads);13521 if (ReturnType.isNull())13522 return;13523 13524 if (IsCompare) {13525 // There are two cases here. If there is null constant, the only suggest13526 // for a pointer return type. If the null is 0, then suggest if the return13527 // type is a pointer or an integer type.13528 if (!ReturnType->isPointerType()) {13529 if (NullKind == Expr::NPCK_ZeroExpression ||13530 NullKind == Expr::NPCK_ZeroLiteral) {13531 if (!ReturnType->isIntegerType())13532 return;13533 } else {13534 return;13535 }13536 }13537 } else { // !IsCompare13538 // For function to bool, only suggest if the function pointer has bool13539 // return type.13540 if (!ReturnType->isSpecificBuiltinType(BuiltinType::Bool))13541 return;13542 }13543 Diag(E->getExprLoc(), diag::note_function_to_function_call)13544 << FixItHint::CreateInsertion(getLocForEndOfToken(E->getEndLoc()), "()");13545}13546 13547void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) {13548 // Don't diagnose in unevaluated contexts.13549 if (isUnevaluatedContext())13550 return;13551 13552 // Don't diagnose for value- or type-dependent expressions.13553 if (E->isTypeDependent() || E->isValueDependent())13554 return;13555 13556 // Check for array bounds violations in cases where the check isn't triggered13557 // elsewhere for other Expr types (like BinaryOperators), e.g. when an13558 // ArraySubscriptExpr is on the RHS of a variable initialization.13559 CheckArrayAccess(E);13560 13561 // This is not the right CC for (e.g.) a variable initialization.13562 AnalyzeImplicitConversions(*this, E, CC);13563}13564 13565void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) {13566 ::CheckBoolLikeConversion(*this, E, CC);13567}13568 13569void Sema::CheckForIntOverflow (const Expr *E) {13570 // Use a work list to deal with nested struct initializers.13571 SmallVector<const Expr *, 2> Exprs(1, E);13572 13573 do {13574 const Expr *OriginalE = Exprs.pop_back_val();13575 const Expr *E = OriginalE->IgnoreParenCasts();13576 13577 if (isa<BinaryOperator, UnaryOperator>(E)) {13578 E->EvaluateForOverflow(Context);13579 continue;13580 }13581 13582 if (const auto *InitList = dyn_cast<InitListExpr>(OriginalE))13583 Exprs.append(InitList->inits().begin(), InitList->inits().end());13584 else if (isa<ObjCBoxedExpr>(OriginalE))13585 E->EvaluateForOverflow(Context);13586 else if (const auto *Call = dyn_cast<CallExpr>(E))13587 Exprs.append(Call->arg_begin(), Call->arg_end());13588 else if (const auto *Message = dyn_cast<ObjCMessageExpr>(E))13589 Exprs.append(Message->arg_begin(), Message->arg_end());13590 else if (const auto *Construct = dyn_cast<CXXConstructExpr>(E))13591 Exprs.append(Construct->arg_begin(), Construct->arg_end());13592 else if (const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))13593 Exprs.push_back(Temporary->getSubExpr());13594 else if (const auto *Array = dyn_cast<ArraySubscriptExpr>(E))13595 Exprs.push_back(Array->getIdx());13596 else if (const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))13597 Exprs.push_back(Compound->getInitializer());13598 else if (const auto *New = dyn_cast<CXXNewExpr>(E);13599 New && New->isArray()) {13600 if (auto ArraySize = New->getArraySize())13601 Exprs.push_back(*ArraySize);13602 } else if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))13603 Exprs.push_back(MTE->getSubExpr());13604 } while (!Exprs.empty());13605}13606 13607namespace {13608 13609/// Visitor for expressions which looks for unsequenced operations on the13610/// same object.13611class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {13612 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;13613 13614 /// A tree of sequenced regions within an expression. Two regions are13615 /// unsequenced if one is an ancestor or a descendent of the other. When we13616 /// finish processing an expression with sequencing, such as a comma13617 /// expression, we fold its tree nodes into its parent, since they are13618 /// unsequenced with respect to nodes we will visit later.13619 class SequenceTree {13620 struct Value {13621 explicit Value(unsigned Parent) : Parent(Parent), Merged(false) {}13622 unsigned Parent : 31;13623 LLVM_PREFERRED_TYPE(bool)13624 unsigned Merged : 1;13625 };13626 SmallVector<Value, 8> Values;13627 13628 public:13629 /// A region within an expression which may be sequenced with respect13630 /// to some other region.13631 class Seq {13632 friend class SequenceTree;13633 13634 unsigned Index;13635 13636 explicit Seq(unsigned N) : Index(N) {}13637 13638 public:13639 Seq() : Index(0) {}13640 };13641 13642 SequenceTree() { Values.push_back(Value(0)); }13643 Seq root() const { return Seq(0); }13644 13645 /// Create a new sequence of operations, which is an unsequenced13646 /// subset of \p Parent. This sequence of operations is sequenced with13647 /// respect to other children of \p Parent.13648 Seq allocate(Seq Parent) {13649 Values.push_back(Value(Parent.Index));13650 return Seq(Values.size() - 1);13651 }13652 13653 /// Merge a sequence of operations into its parent.13654 void merge(Seq S) {13655 Values[S.Index].Merged = true;13656 }13657 13658 /// Determine whether two operations are unsequenced. This operation13659 /// is asymmetric: \p Cur should be the more recent sequence, and \p Old13660 /// should have been merged into its parent as appropriate.13661 bool isUnsequenced(Seq Cur, Seq Old) {13662 unsigned C = representative(Cur.Index);13663 unsigned Target = representative(Old.Index);13664 while (C >= Target) {13665 if (C == Target)13666 return true;13667 C = Values[C].Parent;13668 }13669 return false;13670 }13671 13672 private:13673 /// Pick a representative for a sequence.13674 unsigned representative(unsigned K) {13675 if (Values[K].Merged)13676 // Perform path compression as we go.13677 return Values[K].Parent = representative(Values[K].Parent);13678 return K;13679 }13680 };13681 13682 /// An object for which we can track unsequenced uses.13683 using Object = const NamedDecl *;13684 13685 /// Different flavors of object usage which we track. We only track the13686 /// least-sequenced usage of each kind.13687 enum UsageKind {13688 /// A read of an object. Multiple unsequenced reads are OK.13689 UK_Use,13690 13691 /// A modification of an object which is sequenced before the value13692 /// computation of the expression, such as ++n in C++.13693 UK_ModAsValue,13694 13695 /// A modification of an object which is not sequenced before the value13696 /// computation of the expression, such as n++.13697 UK_ModAsSideEffect,13698 13699 UK_Count = UK_ModAsSideEffect + 113700 };13701 13702 /// Bundle together a sequencing region and the expression corresponding13703 /// to a specific usage. One Usage is stored for each usage kind in UsageInfo.13704 struct Usage {13705 const Expr *UsageExpr = nullptr;13706 SequenceTree::Seq Seq;13707 13708 Usage() = default;13709 };13710 13711 struct UsageInfo {13712 Usage Uses[UK_Count];13713 13714 /// Have we issued a diagnostic for this object already?13715 bool Diagnosed = false;13716 13717 UsageInfo();13718 };13719 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;13720 13721 Sema &SemaRef;13722 13723 /// Sequenced regions within the expression.13724 SequenceTree Tree;13725 13726 /// Declaration modifications and references which we have seen.13727 UsageInfoMap UsageMap;13728 13729 /// The region we are currently within.13730 SequenceTree::Seq Region;13731 13732 /// Filled in with declarations which were modified as a side-effect13733 /// (that is, post-increment operations).13734 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect = nullptr;13735 13736 /// Expressions to check later. We defer checking these to reduce13737 /// stack usage.13738 SmallVectorImpl<const Expr *> &WorkList;13739 13740 /// RAII object wrapping the visitation of a sequenced subexpression of an13741 /// expression. At the end of this process, the side-effects of the evaluation13742 /// become sequenced with respect to the value computation of the result, so13743 /// we downgrade any UK_ModAsSideEffect within the evaluation to13744 /// UK_ModAsValue.13745 struct SequencedSubexpression {13746 SequencedSubexpression(SequenceChecker &Self)13747 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {13748 Self.ModAsSideEffect = &ModAsSideEffect;13749 }13750 13751 ~SequencedSubexpression() {13752 for (const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {13753 // Add a new usage with usage kind UK_ModAsValue, and then restore13754 // the previous usage with UK_ModAsSideEffect (thus clearing it if13755 // the previous one was empty).13756 UsageInfo &UI = Self.UsageMap[M.first];13757 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];13758 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);13759 SideEffectUsage = M.second;13760 }13761 Self.ModAsSideEffect = OldModAsSideEffect;13762 }13763 13764 SequenceChecker &Self;13765 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;13766 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;13767 };13768 13769 /// RAII object wrapping the visitation of a subexpression which we might13770 /// choose to evaluate as a constant. If any subexpression is evaluated and13771 /// found to be non-constant, this allows us to suppress the evaluation of13772 /// the outer expression.13773 class EvaluationTracker {13774 public:13775 EvaluationTracker(SequenceChecker &Self)13776 : Self(Self), Prev(Self.EvalTracker) {13777 Self.EvalTracker = this;13778 }13779 13780 ~EvaluationTracker() {13781 Self.EvalTracker = Prev;13782 if (Prev)13783 Prev->EvalOK &= EvalOK;13784 }13785 13786 bool evaluate(const Expr *E, bool &Result) {13787 if (!EvalOK || E->isValueDependent())13788 return false;13789 EvalOK = E->EvaluateAsBooleanCondition(13790 Result, Self.SemaRef.Context,13791 Self.SemaRef.isConstantEvaluatedContext());13792 return EvalOK;13793 }13794 13795 private:13796 SequenceChecker &Self;13797 EvaluationTracker *Prev;13798 bool EvalOK = true;13799 } *EvalTracker = nullptr;13800 13801 /// Find the object which is produced by the specified expression,13802 /// if any.13803 Object getObject(const Expr *E, bool Mod) const {13804 E = E->IgnoreParenCasts();13805 if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {13806 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))13807 return getObject(UO->getSubExpr(), Mod);13808 } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {13809 if (BO->getOpcode() == BO_Comma)13810 return getObject(BO->getRHS(), Mod);13811 if (Mod && BO->isAssignmentOp())13812 return getObject(BO->getLHS(), Mod);13813 } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {13814 // FIXME: Check for more interesting cases, like "x.n = ++x.n".13815 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))13816 return ME->getMemberDecl();13817 } else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))13818 // FIXME: If this is a reference, map through to its value.13819 return DRE->getDecl();13820 return nullptr;13821 }13822 13823 /// Note that an object \p O was modified or used by an expression13824 /// \p UsageExpr with usage kind \p UK. \p UI is the \p UsageInfo for13825 /// the object \p O as obtained via the \p UsageMap.13826 void addUsage(Object O, UsageInfo &UI, const Expr *UsageExpr, UsageKind UK) {13827 // Get the old usage for the given object and usage kind.13828 Usage &U = UI.Uses[UK];13829 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {13830 // If we have a modification as side effect and are in a sequenced13831 // subexpression, save the old Usage so that we can restore it later13832 // in SequencedSubexpression::~SequencedSubexpression.13833 if (UK == UK_ModAsSideEffect && ModAsSideEffect)13834 ModAsSideEffect->push_back(std::make_pair(O, U));13835 // Then record the new usage with the current sequencing region.13836 U.UsageExpr = UsageExpr;13837 U.Seq = Region;13838 }13839 }13840 13841 /// Check whether a modification or use of an object \p O in an expression13842 /// \p UsageExpr conflicts with a prior usage of kind \p OtherKind. \p UI is13843 /// the \p UsageInfo for the object \p O as obtained via the \p UsageMap.13844 /// \p IsModMod is true when we are checking for a mod-mod unsequenced13845 /// usage and false we are checking for a mod-use unsequenced usage.13846 void checkUsage(Object O, UsageInfo &UI, const Expr *UsageExpr,13847 UsageKind OtherKind, bool IsModMod) {13848 if (UI.Diagnosed)13849 return;13850 13851 const Usage &U = UI.Uses[OtherKind];13852 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))13853 return;13854 13855 const Expr *Mod = U.UsageExpr;13856 const Expr *ModOrUse = UsageExpr;13857 if (OtherKind == UK_Use)13858 std::swap(Mod, ModOrUse);13859 13860 SemaRef.DiagRuntimeBehavior(13861 Mod->getExprLoc(), {Mod, ModOrUse},13862 SemaRef.PDiag(IsModMod ? diag::warn_unsequenced_mod_mod13863 : diag::warn_unsequenced_mod_use)13864 << O << SourceRange(ModOrUse->getExprLoc()));13865 UI.Diagnosed = true;13866 }13867 13868 // A note on note{Pre, Post}{Use, Mod}:13869 //13870 // (It helps to follow the algorithm with an expression such as13871 // "((++k)++, k) = k" or "k = (k++, k++)". Both contain unsequenced13872 // operations before C++17 and both are well-defined in C++17).13873 //13874 // When visiting a node which uses/modify an object we first call notePreUse13875 // or notePreMod before visiting its sub-expression(s). At this point the13876 // children of the current node have not yet been visited and so the eventual13877 // uses/modifications resulting from the children of the current node have not13878 // been recorded yet.13879 //13880 // We then visit the children of the current node. After that notePostUse or13881 // notePostMod is called. These will 1) detect an unsequenced modification13882 // as side effect (as in "k++ + k") and 2) add a new usage with the13883 // appropriate usage kind.13884 //13885 // We also have to be careful that some operation sequences modification as13886 // side effect as well (for example: || or ,). To account for this we wrap13887 // the visitation of such a sub-expression (for example: the LHS of || or ,)13888 // with SequencedSubexpression. SequencedSubexpression is an RAII object13889 // which record usages which are modifications as side effect, and then13890 // downgrade them (or more accurately restore the previous usage which was a13891 // modification as side effect) when exiting the scope of the sequenced13892 // subexpression.13893 13894 void notePreUse(Object O, const Expr *UseExpr) {13895 UsageInfo &UI = UsageMap[O];13896 // Uses conflict with other modifications.13897 checkUsage(O, UI, UseExpr, /*OtherKind=*/UK_ModAsValue, /*IsModMod=*/false);13898 }13899 13900 void notePostUse(Object O, const Expr *UseExpr) {13901 UsageInfo &UI = UsageMap[O];13902 checkUsage(O, UI, UseExpr, /*OtherKind=*/UK_ModAsSideEffect,13903 /*IsModMod=*/false);13904 addUsage(O, UI, UseExpr, /*UsageKind=*/UK_Use);13905 }13906 13907 void notePreMod(Object O, const Expr *ModExpr) {13908 UsageInfo &UI = UsageMap[O];13909 // Modifications conflict with other modifications and with uses.13910 checkUsage(O, UI, ModExpr, /*OtherKind=*/UK_ModAsValue, /*IsModMod=*/true);13911 checkUsage(O, UI, ModExpr, /*OtherKind=*/UK_Use, /*IsModMod=*/false);13912 }13913 13914 void notePostMod(Object O, const Expr *ModExpr, UsageKind UK) {13915 UsageInfo &UI = UsageMap[O];13916 checkUsage(O, UI, ModExpr, /*OtherKind=*/UK_ModAsSideEffect,13917 /*IsModMod=*/true);13918 addUsage(O, UI, ModExpr, /*UsageKind=*/UK);13919 }13920 13921public:13922 SequenceChecker(Sema &S, const Expr *E,13923 SmallVectorImpl<const Expr *> &WorkList)13924 : Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {13925 Visit(E);13926 // Silence a -Wunused-private-field since WorkList is now unused.13927 // TODO: Evaluate if it can be used, and if not remove it.13928 (void)this->WorkList;13929 }13930 13931 void VisitStmt(const Stmt *S) {13932 // Skip all statements which aren't expressions for now.13933 }13934 13935 void VisitExpr(const Expr *E) {13936 // By default, just recurse to evaluated subexpressions.13937 Base::VisitStmt(E);13938 }13939 13940 void VisitCoroutineSuspendExpr(const CoroutineSuspendExpr *CSE) {13941 for (auto *Sub : CSE->children()) {13942 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);13943 if (!ChildExpr)13944 continue;13945 13946 if (ChildExpr == CSE->getOperand())13947 // Do not recurse over a CoroutineSuspendExpr's operand.13948 // The operand is also a subexpression of getCommonExpr(), and13949 // recursing into it directly could confuse object management13950 // for the sake of sequence tracking.13951 continue;13952 13953 Visit(Sub);13954 }13955 }13956 13957 void VisitCastExpr(const CastExpr *E) {13958 Object O = Object();13959 if (E->getCastKind() == CK_LValueToRValue)13960 O = getObject(E->getSubExpr(), false);13961 13962 if (O)13963 notePreUse(O, E);13964 VisitExpr(E);13965 if (O)13966 notePostUse(O, E);13967 }13968 13969 void VisitSequencedExpressions(const Expr *SequencedBefore,13970 const Expr *SequencedAfter) {13971 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);13972 SequenceTree::Seq AfterRegion = Tree.allocate(Region);13973 SequenceTree::Seq OldRegion = Region;13974 13975 {13976 SequencedSubexpression SeqBefore(*this);13977 Region = BeforeRegion;13978 Visit(SequencedBefore);13979 }13980 13981 Region = AfterRegion;13982 Visit(SequencedAfter);13983 13984 Region = OldRegion;13985 13986 Tree.merge(BeforeRegion);13987 Tree.merge(AfterRegion);13988 }13989 13990 void VisitArraySubscriptExpr(const ArraySubscriptExpr *ASE) {13991 // C++17 [expr.sub]p1:13992 // The expression E1[E2] is identical (by definition) to *((E1)+(E2)). The13993 // expression E1 is sequenced before the expression E2.13994 if (SemaRef.getLangOpts().CPlusPlus17)13995 VisitSequencedExpressions(ASE->getLHS(), ASE->getRHS());13996 else {13997 Visit(ASE->getLHS());13998 Visit(ASE->getRHS());13999 }14000 }14001 14002 void VisitBinPtrMemD(const BinaryOperator *BO) { VisitBinPtrMem(BO); }14003 void VisitBinPtrMemI(const BinaryOperator *BO) { VisitBinPtrMem(BO); }14004 void VisitBinPtrMem(const BinaryOperator *BO) {14005 // C++17 [expr.mptr.oper]p4:14006 // Abbreviating pm-expression.*cast-expression as E1.*E2, [...]14007 // the expression E1 is sequenced before the expression E2.14008 if (SemaRef.getLangOpts().CPlusPlus17)14009 VisitSequencedExpressions(BO->getLHS(), BO->getRHS());14010 else {14011 Visit(BO->getLHS());14012 Visit(BO->getRHS());14013 }14014 }14015 14016 void VisitBinShl(const BinaryOperator *BO) { VisitBinShlShr(BO); }14017 void VisitBinShr(const BinaryOperator *BO) { VisitBinShlShr(BO); }14018 void VisitBinShlShr(const BinaryOperator *BO) {14019 // C++17 [expr.shift]p4:14020 // The expression E1 is sequenced before the expression E2.14021 if (SemaRef.getLangOpts().CPlusPlus17)14022 VisitSequencedExpressions(BO->getLHS(), BO->getRHS());14023 else {14024 Visit(BO->getLHS());14025 Visit(BO->getRHS());14026 }14027 }14028 14029 void VisitBinComma(const BinaryOperator *BO) {14030 // C++11 [expr.comma]p1:14031 // Every value computation and side effect associated with the left14032 // expression is sequenced before every value computation and side14033 // effect associated with the right expression.14034 VisitSequencedExpressions(BO->getLHS(), BO->getRHS());14035 }14036 14037 void VisitBinAssign(const BinaryOperator *BO) {14038 SequenceTree::Seq RHSRegion;14039 SequenceTree::Seq LHSRegion;14040 if (SemaRef.getLangOpts().CPlusPlus17) {14041 RHSRegion = Tree.allocate(Region);14042 LHSRegion = Tree.allocate(Region);14043 } else {14044 RHSRegion = Region;14045 LHSRegion = Region;14046 }14047 SequenceTree::Seq OldRegion = Region;14048 14049 // C++11 [expr.ass]p1:14050 // [...] the assignment is sequenced after the value computation14051 // of the right and left operands, [...]14052 //14053 // so check it before inspecting the operands and update the14054 // map afterwards.14055 Object O = getObject(BO->getLHS(), /*Mod=*/true);14056 if (O)14057 notePreMod(O, BO);14058 14059 if (SemaRef.getLangOpts().CPlusPlus17) {14060 // C++17 [expr.ass]p1:14061 // [...] The right operand is sequenced before the left operand. [...]14062 {14063 SequencedSubexpression SeqBefore(*this);14064 Region = RHSRegion;14065 Visit(BO->getRHS());14066 }14067 14068 Region = LHSRegion;14069 Visit(BO->getLHS());14070 14071 if (O && isa<CompoundAssignOperator>(BO))14072 notePostUse(O, BO);14073 14074 } else {14075 // C++11 does not specify any sequencing between the LHS and RHS.14076 Region = LHSRegion;14077 Visit(BO->getLHS());14078 14079 if (O && isa<CompoundAssignOperator>(BO))14080 notePostUse(O, BO);14081 14082 Region = RHSRegion;14083 Visit(BO->getRHS());14084 }14085 14086 // C++11 [expr.ass]p1:14087 // the assignment is sequenced [...] before the value computation of the14088 // assignment expression.14089 // C11 6.5.16/3 has no such rule.14090 Region = OldRegion;14091 if (O)14092 notePostMod(O, BO,14093 SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue14094 : UK_ModAsSideEffect);14095 if (SemaRef.getLangOpts().CPlusPlus17) {14096 Tree.merge(RHSRegion);14097 Tree.merge(LHSRegion);14098 }14099 }14100 14101 void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO) {14102 VisitBinAssign(CAO);14103 }14104 14105 void VisitUnaryPreInc(const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }14106 void VisitUnaryPreDec(const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }14107 void VisitUnaryPreIncDec(const UnaryOperator *UO) {14108 Object O = getObject(UO->getSubExpr(), true);14109 if (!O)14110 return VisitExpr(UO);14111 14112 notePreMod(O, UO);14113 Visit(UO->getSubExpr());14114 // C++11 [expr.pre.incr]p1:14115 // the expression ++x is equivalent to x+=114116 notePostMod(O, UO,14117 SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue14118 : UK_ModAsSideEffect);14119 }14120 14121 void VisitUnaryPostInc(const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }14122 void VisitUnaryPostDec(const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }14123 void VisitUnaryPostIncDec(const UnaryOperator *UO) {14124 Object O = getObject(UO->getSubExpr(), true);14125 if (!O)14126 return VisitExpr(UO);14127 14128 notePreMod(O, UO);14129 Visit(UO->getSubExpr());14130 notePostMod(O, UO, UK_ModAsSideEffect);14131 }14132 14133 void VisitBinLOr(const BinaryOperator *BO) {14134 // C++11 [expr.log.or]p2:14135 // If the second expression is evaluated, every value computation and14136 // side effect associated with the first expression is sequenced before14137 // every value computation and side effect associated with the14138 // second expression.14139 SequenceTree::Seq LHSRegion = Tree.allocate(Region);14140 SequenceTree::Seq RHSRegion = Tree.allocate(Region);14141 SequenceTree::Seq OldRegion = Region;14142 14143 EvaluationTracker Eval(*this);14144 {14145 SequencedSubexpression Sequenced(*this);14146 Region = LHSRegion;14147 Visit(BO->getLHS());14148 }14149 14150 // C++11 [expr.log.or]p1:14151 // [...] the second operand is not evaluated if the first operand14152 // evaluates to true.14153 bool EvalResult = false;14154 bool EvalOK = Eval.evaluate(BO->getLHS(), EvalResult);14155 bool ShouldVisitRHS = !EvalOK || !EvalResult;14156 if (ShouldVisitRHS) {14157 Region = RHSRegion;14158 Visit(BO->getRHS());14159 }14160 14161 Region = OldRegion;14162 Tree.merge(LHSRegion);14163 Tree.merge(RHSRegion);14164 }14165 14166 void VisitBinLAnd(const BinaryOperator *BO) {14167 // C++11 [expr.log.and]p2:14168 // If the second expression is evaluated, every value computation and14169 // side effect associated with the first expression is sequenced before14170 // every value computation and side effect associated with the14171 // second expression.14172 SequenceTree::Seq LHSRegion = Tree.allocate(Region);14173 SequenceTree::Seq RHSRegion = Tree.allocate(Region);14174 SequenceTree::Seq OldRegion = Region;14175 14176 EvaluationTracker Eval(*this);14177 {14178 SequencedSubexpression Sequenced(*this);14179 Region = LHSRegion;14180 Visit(BO->getLHS());14181 }14182 14183 // C++11 [expr.log.and]p1:14184 // [...] the second operand is not evaluated if the first operand is false.14185 bool EvalResult = false;14186 bool EvalOK = Eval.evaluate(BO->getLHS(), EvalResult);14187 bool ShouldVisitRHS = !EvalOK || EvalResult;14188 if (ShouldVisitRHS) {14189 Region = RHSRegion;14190 Visit(BO->getRHS());14191 }14192 14193 Region = OldRegion;14194 Tree.merge(LHSRegion);14195 Tree.merge(RHSRegion);14196 }14197 14198 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO) {14199 // C++11 [expr.cond]p1:14200 // [...] Every value computation and side effect associated with the first14201 // expression is sequenced before every value computation and side effect14202 // associated with the second or third expression.14203 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);14204 14205 // No sequencing is specified between the true and false expression.14206 // However since exactly one of both is going to be evaluated we can14207 // consider them to be sequenced. This is needed to avoid warning on14208 // something like "x ? y+= 1 : y += 2;" in the case where we will visit14209 // both the true and false expressions because we can't evaluate x.14210 // This will still allow us to detect an expression like (pre C++17)14211 // "(x ? y += 1 : y += 2) = y".14212 //14213 // We don't wrap the visitation of the true and false expression with14214 // SequencedSubexpression because we don't want to downgrade modifications14215 // as side effect in the true and false expressions after the visition14216 // is done. (for example in the expression "(x ? y++ : y++) + y" we should14217 // not warn between the two "y++", but we should warn between the "y++"14218 // and the "y".14219 SequenceTree::Seq TrueRegion = Tree.allocate(Region);14220 SequenceTree::Seq FalseRegion = Tree.allocate(Region);14221 SequenceTree::Seq OldRegion = Region;14222 14223 EvaluationTracker Eval(*this);14224 {14225 SequencedSubexpression Sequenced(*this);14226 Region = ConditionRegion;14227 Visit(CO->getCond());14228 }14229 14230 // C++11 [expr.cond]p1:14231 // [...] The first expression is contextually converted to bool (Clause 4).14232 // It is evaluated and if it is true, the result of the conditional14233 // expression is the value of the second expression, otherwise that of the14234 // third expression. Only one of the second and third expressions is14235 // evaluated. [...]14236 bool EvalResult = false;14237 bool EvalOK = Eval.evaluate(CO->getCond(), EvalResult);14238 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;14239 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;14240 if (ShouldVisitTrueExpr) {14241 Region = TrueRegion;14242 Visit(CO->getTrueExpr());14243 }14244 if (ShouldVisitFalseExpr) {14245 Region = FalseRegion;14246 Visit(CO->getFalseExpr());14247 }14248 14249 Region = OldRegion;14250 Tree.merge(ConditionRegion);14251 Tree.merge(TrueRegion);14252 Tree.merge(FalseRegion);14253 }14254 14255 void VisitCallExpr(const CallExpr *CE) {14256 // FIXME: CXXNewExpr and CXXDeleteExpr implicitly call functions.14257 14258 if (CE->isUnevaluatedBuiltinCall(Context))14259 return;14260 14261 // C++11 [intro.execution]p15:14262 // When calling a function [...], every value computation and side effect14263 // associated with any argument expression, or with the postfix expression14264 // designating the called function, is sequenced before execution of every14265 // expression or statement in the body of the function [and thus before14266 // the value computation of its result].14267 SequencedSubexpression Sequenced(*this);14268 SemaRef.runWithSufficientStackSpace(CE->getExprLoc(), [&] {14269 // C++17 [expr.call]p514270 // The postfix-expression is sequenced before each expression in the14271 // expression-list and any default argument. [...]14272 SequenceTree::Seq CalleeRegion;14273 SequenceTree::Seq OtherRegion;14274 if (SemaRef.getLangOpts().CPlusPlus17) {14275 CalleeRegion = Tree.allocate(Region);14276 OtherRegion = Tree.allocate(Region);14277 } else {14278 CalleeRegion = Region;14279 OtherRegion = Region;14280 }14281 SequenceTree::Seq OldRegion = Region;14282 14283 // Visit the callee expression first.14284 Region = CalleeRegion;14285 if (SemaRef.getLangOpts().CPlusPlus17) {14286 SequencedSubexpression Sequenced(*this);14287 Visit(CE->getCallee());14288 } else {14289 Visit(CE->getCallee());14290 }14291 14292 // Then visit the argument expressions.14293 Region = OtherRegion;14294 for (const Expr *Argument : CE->arguments())14295 Visit(Argument);14296 14297 Region = OldRegion;14298 if (SemaRef.getLangOpts().CPlusPlus17) {14299 Tree.merge(CalleeRegion);14300 Tree.merge(OtherRegion);14301 }14302 });14303 }14304 14305 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CXXOCE) {14306 // C++17 [over.match.oper]p2:14307 // [...] the operator notation is first transformed to the equivalent14308 // function-call notation as summarized in Table 12 (where @ denotes one14309 // of the operators covered in the specified subclause). However, the14310 // operands are sequenced in the order prescribed for the built-in14311 // operator (Clause 8).14312 //14313 // From the above only overloaded binary operators and overloaded call14314 // operators have sequencing rules in C++17 that we need to handle14315 // separately.14316 if (!SemaRef.getLangOpts().CPlusPlus17 ||14317 (CXXOCE->getNumArgs() != 2 && CXXOCE->getOperator() != OO_Call))14318 return VisitCallExpr(CXXOCE);14319 14320 enum {14321 NoSequencing,14322 LHSBeforeRHS,14323 RHSBeforeLHS,14324 LHSBeforeRest14325 } SequencingKind;14326 switch (CXXOCE->getOperator()) {14327 case OO_Equal:14328 case OO_PlusEqual:14329 case OO_MinusEqual:14330 case OO_StarEqual:14331 case OO_SlashEqual:14332 case OO_PercentEqual:14333 case OO_CaretEqual:14334 case OO_AmpEqual:14335 case OO_PipeEqual:14336 case OO_LessLessEqual:14337 case OO_GreaterGreaterEqual:14338 SequencingKind = RHSBeforeLHS;14339 break;14340 14341 case OO_LessLess:14342 case OO_GreaterGreater:14343 case OO_AmpAmp:14344 case OO_PipePipe:14345 case OO_Comma:14346 case OO_ArrowStar:14347 case OO_Subscript:14348 SequencingKind = LHSBeforeRHS;14349 break;14350 14351 case OO_Call:14352 SequencingKind = LHSBeforeRest;14353 break;14354 14355 default:14356 SequencingKind = NoSequencing;14357 break;14358 }14359 14360 if (SequencingKind == NoSequencing)14361 return VisitCallExpr(CXXOCE);14362 14363 // This is a call, so all subexpressions are sequenced before the result.14364 SequencedSubexpression Sequenced(*this);14365 14366 SemaRef.runWithSufficientStackSpace(CXXOCE->getExprLoc(), [&] {14367 assert(SemaRef.getLangOpts().CPlusPlus17 &&14368 "Should only get there with C++17 and above!");14369 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&14370 "Should only get there with an overloaded binary operator"14371 " or an overloaded call operator!");14372 14373 if (SequencingKind == LHSBeforeRest) {14374 assert(CXXOCE->getOperator() == OO_Call &&14375 "We should only have an overloaded call operator here!");14376 14377 // This is very similar to VisitCallExpr, except that we only have the14378 // C++17 case. The postfix-expression is the first argument of the14379 // CXXOperatorCallExpr. The expressions in the expression-list, if any,14380 // are in the following arguments.14381 //14382 // Note that we intentionally do not visit the callee expression since14383 // it is just a decayed reference to a function.14384 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);14385 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);14386 SequenceTree::Seq OldRegion = Region;14387 14388 assert(CXXOCE->getNumArgs() >= 1 &&14389 "An overloaded call operator must have at least one argument"14390 " for the postfix-expression!");14391 const Expr *PostfixExpr = CXXOCE->getArgs()[0];14392 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,14393 CXXOCE->getNumArgs() - 1);14394 14395 // Visit the postfix-expression first.14396 {14397 Region = PostfixExprRegion;14398 SequencedSubexpression Sequenced(*this);14399 Visit(PostfixExpr);14400 }14401 14402 // Then visit the argument expressions.14403 Region = ArgsRegion;14404 for (const Expr *Arg : Args)14405 Visit(Arg);14406 14407 Region = OldRegion;14408 Tree.merge(PostfixExprRegion);14409 Tree.merge(ArgsRegion);14410 } else {14411 assert(CXXOCE->getNumArgs() == 2 &&14412 "Should only have two arguments here!");14413 assert((SequencingKind == LHSBeforeRHS ||14414 SequencingKind == RHSBeforeLHS) &&14415 "Unexpected sequencing kind!");14416 14417 // We do not visit the callee expression since it is just a decayed14418 // reference to a function.14419 const Expr *E1 = CXXOCE->getArg(0);14420 const Expr *E2 = CXXOCE->getArg(1);14421 if (SequencingKind == RHSBeforeLHS)14422 std::swap(E1, E2);14423 14424 return VisitSequencedExpressions(E1, E2);14425 }14426 });14427 }14428 14429 void VisitCXXConstructExpr(const CXXConstructExpr *CCE) {14430 // This is a call, so all subexpressions are sequenced before the result.14431 SequencedSubexpression Sequenced(*this);14432 14433 if (!CCE->isListInitialization())14434 return VisitExpr(CCE);14435 14436 // In C++11, list initializations are sequenced.14437 SequenceExpressionsInOrder(14438 llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs()));14439 }14440 14441 void VisitInitListExpr(const InitListExpr *ILE) {14442 if (!SemaRef.getLangOpts().CPlusPlus11)14443 return VisitExpr(ILE);14444 14445 // In C++11, list initializations are sequenced.14446 SequenceExpressionsInOrder(ILE->inits());14447 }14448 14449 void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {14450 // C++20 parenthesized list initializations are sequenced. See C++2014451 // [decl.init.general]p16.5 and [decl.init.general]p16.6.2.2.14452 SequenceExpressionsInOrder(PLIE->getInitExprs());14453 }14454 14455private:14456 void SequenceExpressionsInOrder(ArrayRef<const Expr *> ExpressionList) {14457 SmallVector<SequenceTree::Seq, 32> Elts;14458 SequenceTree::Seq Parent = Region;14459 for (const Expr *E : ExpressionList) {14460 if (!E)14461 continue;14462 Region = Tree.allocate(Parent);14463 Elts.push_back(Region);14464 Visit(E);14465 }14466 14467 // Forget that the initializers are sequenced.14468 Region = Parent;14469 for (unsigned I = 0; I < Elts.size(); ++I)14470 Tree.merge(Elts[I]);14471 }14472};14473 14474SequenceChecker::UsageInfo::UsageInfo() = default;14475 14476} // namespace14477 14478void Sema::CheckUnsequencedOperations(const Expr *E) {14479 SmallVector<const Expr *, 8> WorkList;14480 WorkList.push_back(E);14481 while (!WorkList.empty()) {14482 const Expr *Item = WorkList.pop_back_val();14483 SequenceChecker(*this, Item, WorkList);14484 }14485}14486 14487void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc,14488 bool IsConstexpr) {14489 llvm::SaveAndRestore ConstantContext(isConstantEvaluatedOverride,14490 IsConstexpr || isa<ConstantExpr>(E));14491 CheckImplicitConversions(E, CheckLoc);14492 if (!E->isInstantiationDependent())14493 CheckUnsequencedOperations(E);14494 if (!IsConstexpr && !E->isValueDependent())14495 CheckForIntOverflow(E);14496}14497 14498void Sema::CheckBitFieldInitialization(SourceLocation InitLoc,14499 FieldDecl *BitField,14500 Expr *Init) {14501 (void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc);14502}14503 14504static void diagnoseArrayStarInParamType(Sema &S, QualType PType,14505 SourceLocation Loc) {14506 if (!PType->isVariablyModifiedType())14507 return;14508 if (const auto *PointerTy = dyn_cast<PointerType>(PType)) {14509 diagnoseArrayStarInParamType(S, PointerTy->getPointeeType(), Loc);14510 return;14511 }14512 if (const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {14513 diagnoseArrayStarInParamType(S, ReferenceTy->getPointeeType(), Loc);14514 return;14515 }14516 if (const auto *ParenTy = dyn_cast<ParenType>(PType)) {14517 diagnoseArrayStarInParamType(S, ParenTy->getInnerType(), Loc);14518 return;14519 }14520 14521 const ArrayType *AT = S.Context.getAsArrayType(PType);14522 if (!AT)14523 return;14524 14525 if (AT->getSizeModifier() != ArraySizeModifier::Star) {14526 diagnoseArrayStarInParamType(S, AT->getElementType(), Loc);14527 return;14528 }14529 14530 S.Diag(Loc, diag::err_array_star_in_function_definition);14531}14532 14533bool Sema::CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters,14534 bool CheckParameterNames) {14535 bool HasInvalidParm = false;14536 for (ParmVarDecl *Param : Parameters) {14537 assert(Param && "null in a parameter list");14538 // C99 6.7.5.3p4: the parameters in a parameter type list in a14539 // function declarator that is part of a function definition of14540 // that function shall not have incomplete type.14541 //14542 // C++23 [dcl.fct.def.general]/p214543 // The type of a parameter [...] for a function definition14544 // shall not be a (possibly cv-qualified) class type that is incomplete14545 // or abstract within the function body unless the function is deleted.14546 if (!Param->isInvalidDecl() &&14547 (RequireCompleteType(Param->getLocation(), Param->getType(),14548 diag::err_typecheck_decl_incomplete_type) ||14549 RequireNonAbstractType(Param->getBeginLoc(), Param->getOriginalType(),14550 diag::err_abstract_type_in_decl,14551 AbstractParamType))) {14552 Param->setInvalidDecl();14553 HasInvalidParm = true;14554 }14555 14556 // C99 6.9.1p5: If the declarator includes a parameter type list, the14557 // declaration of each parameter shall include an identifier.14558 if (CheckParameterNames && Param->getIdentifier() == nullptr &&14559 !Param->isImplicit() && !getLangOpts().CPlusPlus) {14560 // Diagnose this as an extension in C17 and earlier.14561 if (!getLangOpts().C23)14562 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);14563 }14564 14565 // C99 6.7.5.3p12:14566 // If the function declarator is not part of a definition of that14567 // function, parameters may have incomplete type and may use the [*]14568 // notation in their sequences of declarator specifiers to specify14569 // variable length array types.14570 QualType PType = Param->getOriginalType();14571 // FIXME: This diagnostic should point the '[*]' if source-location14572 // information is added for it.14573 diagnoseArrayStarInParamType(*this, PType, Param->getLocation());14574 14575 // If the parameter is a c++ class type and it has to be destructed in the14576 // callee function, declare the destructor so that it can be called by the14577 // callee function. Do not perform any direct access check on the dtor here.14578 if (!Param->isInvalidDecl()) {14579 if (CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {14580 if (!ClassDecl->isInvalidDecl() &&14581 !ClassDecl->hasIrrelevantDestructor() &&14582 !ClassDecl->isDependentContext() &&14583 ClassDecl->isParamDestroyedInCallee()) {14584 CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);14585 MarkFunctionReferenced(Param->getLocation(), Destructor);14586 DiagnoseUseOfDecl(Destructor, Param->getLocation());14587 }14588 }14589 }14590 14591 // Parameters with the pass_object_size attribute only need to be marked14592 // constant at function definitions. Because we lack information about14593 // whether we're on a declaration or definition when we're instantiating the14594 // attribute, we need to check for constness here.14595 if (const auto *Attr = Param->getAttr<PassObjectSizeAttr>())14596 if (!Param->getType().isConstQualified())14597 Diag(Param->getLocation(), diag::err_attribute_pointers_only)14598 << Attr->getSpelling() << 1;14599 14600 // Check for parameter names shadowing fields from the class.14601 if (LangOpts.CPlusPlus && !Param->isInvalidDecl()) {14602 // The owning context for the parameter should be the function, but we14603 // want to see if this function's declaration context is a record.14604 DeclContext *DC = Param->getDeclContext();14605 if (DC && DC->isFunctionOrMethod()) {14606 if (auto *RD = dyn_cast<CXXRecordDecl>(DC->getParent()))14607 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),14608 RD, /*DeclIsField*/ false);14609 }14610 }14611 14612 if (!Param->isInvalidDecl() &&14613 Param->getOriginalType()->isWebAssemblyTableType()) {14614 Param->setInvalidDecl();14615 HasInvalidParm = true;14616 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);14617 }14618 }14619 14620 return HasInvalidParm;14621}14622 14623std::optional<std::pair<14624 CharUnits, CharUnits>> static getBaseAlignmentAndOffsetFromPtr(const Expr14625 *E,14626 ASTContext14627 &Ctx);14628 14629/// Compute the alignment and offset of the base class object given the14630/// derived-to-base cast expression and the alignment and offset of the derived14631/// class object.14632static std::pair<CharUnits, CharUnits>14633getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType,14634 CharUnits BaseAlignment, CharUnits Offset,14635 ASTContext &Ctx) {14636 for (auto PathI = CE->path_begin(), PathE = CE->path_end(); PathI != PathE;14637 ++PathI) {14638 const CXXBaseSpecifier *Base = *PathI;14639 const CXXRecordDecl *BaseDecl = Base->getType()->getAsCXXRecordDecl();14640 if (Base->isVirtual()) {14641 // The complete object may have a lower alignment than the non-virtual14642 // alignment of the base, in which case the base may be misaligned. Choose14643 // the smaller of the non-virtual alignment and BaseAlignment, which is a14644 // conservative lower bound of the complete object alignment.14645 CharUnits NonVirtualAlignment =14646 Ctx.getASTRecordLayout(BaseDecl).getNonVirtualAlignment();14647 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);14648 Offset = CharUnits::Zero();14649 } else {14650 const ASTRecordLayout &RL =14651 Ctx.getASTRecordLayout(DerivedType->getAsCXXRecordDecl());14652 Offset += RL.getBaseClassOffset(BaseDecl);14653 }14654 DerivedType = Base->getType();14655 }14656 14657 return std::make_pair(BaseAlignment, Offset);14658}14659 14660/// Compute the alignment and offset of a binary additive operator.14661static std::optional<std::pair<CharUnits, CharUnits>>14662getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE,14663 bool IsSub, ASTContext &Ctx) {14664 QualType PointeeType = PtrE->getType()->getPointeeType();14665 14666 if (!PointeeType->isConstantSizeType())14667 return std::nullopt;14668 14669 auto P = getBaseAlignmentAndOffsetFromPtr(PtrE, Ctx);14670 14671 if (!P)14672 return std::nullopt;14673 14674 CharUnits EltSize = Ctx.getTypeSizeInChars(PointeeType);14675 if (std::optional<llvm::APSInt> IdxRes = IntE->getIntegerConstantExpr(Ctx)) {14676 CharUnits Offset = EltSize * IdxRes->getExtValue();14677 if (IsSub)14678 Offset = -Offset;14679 return std::make_pair(P->first, P->second + Offset);14680 }14681 14682 // If the integer expression isn't a constant expression, compute the lower14683 // bound of the alignment using the alignment and offset of the pointer14684 // expression and the element size.14685 return std::make_pair(14686 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),14687 CharUnits::Zero());14688}14689 14690/// This helper function takes an lvalue expression and returns the alignment of14691/// a VarDecl and a constant offset from the VarDecl.14692std::optional<std::pair<14693 CharUnits,14694 CharUnits>> static getBaseAlignmentAndOffsetFromLValue(const Expr *E,14695 ASTContext &Ctx) {14696 E = E->IgnoreParens();14697 switch (E->getStmtClass()) {14698 default:14699 break;14700 case Stmt::CStyleCastExprClass:14701 case Stmt::CXXStaticCastExprClass:14702 case Stmt::ImplicitCastExprClass: {14703 auto *CE = cast<CastExpr>(E);14704 const Expr *From = CE->getSubExpr();14705 switch (CE->getCastKind()) {14706 default:14707 break;14708 case CK_NoOp:14709 return getBaseAlignmentAndOffsetFromLValue(From, Ctx);14710 case CK_UncheckedDerivedToBase:14711 case CK_DerivedToBase: {14712 auto P = getBaseAlignmentAndOffsetFromLValue(From, Ctx);14713 if (!P)14714 break;14715 return getDerivedToBaseAlignmentAndOffset(CE, From->getType(), P->first,14716 P->second, Ctx);14717 }14718 }14719 break;14720 }14721 case Stmt::ArraySubscriptExprClass: {14722 auto *ASE = cast<ArraySubscriptExpr>(E);14723 return getAlignmentAndOffsetFromBinAddOrSub(ASE->getBase(), ASE->getIdx(),14724 false, Ctx);14725 }14726 case Stmt::DeclRefExprClass: {14727 if (auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl())) {14728 // FIXME: If VD is captured by copy or is an escaping __block variable,14729 // use the alignment of VD's type.14730 if (!VD->getType()->isReferenceType()) {14731 // Dependent alignment cannot be resolved -> bail out.14732 if (VD->hasDependentAlignment())14733 break;14734 return std::make_pair(Ctx.getDeclAlign(VD), CharUnits::Zero());14735 }14736 if (VD->hasInit())14737 return getBaseAlignmentAndOffsetFromLValue(VD->getInit(), Ctx);14738 }14739 break;14740 }14741 case Stmt::MemberExprClass: {14742 auto *ME = cast<MemberExpr>(E);14743 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());14744 if (!FD || FD->getType()->isReferenceType() ||14745 FD->getParent()->isInvalidDecl())14746 break;14747 std::optional<std::pair<CharUnits, CharUnits>> P;14748 if (ME->isArrow())14749 P = getBaseAlignmentAndOffsetFromPtr(ME->getBase(), Ctx);14750 else14751 P = getBaseAlignmentAndOffsetFromLValue(ME->getBase(), Ctx);14752 if (!P)14753 break;14754 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(FD->getParent());14755 uint64_t Offset = Layout.getFieldOffset(FD->getFieldIndex());14756 return std::make_pair(P->first,14757 P->second + CharUnits::fromQuantity(Offset));14758 }14759 case Stmt::UnaryOperatorClass: {14760 auto *UO = cast<UnaryOperator>(E);14761 switch (UO->getOpcode()) {14762 default:14763 break;14764 case UO_Deref:14765 return getBaseAlignmentAndOffsetFromPtr(UO->getSubExpr(), Ctx);14766 }14767 break;14768 }14769 case Stmt::BinaryOperatorClass: {14770 auto *BO = cast<BinaryOperator>(E);14771 auto Opcode = BO->getOpcode();14772 switch (Opcode) {14773 default:14774 break;14775 case BO_Comma:14776 return getBaseAlignmentAndOffsetFromLValue(BO->getRHS(), Ctx);14777 }14778 break;14779 }14780 }14781 return std::nullopt;14782}14783 14784/// This helper function takes a pointer expression and returns the alignment of14785/// a VarDecl and a constant offset from the VarDecl.14786std::optional<std::pair<14787 CharUnits, CharUnits>> static getBaseAlignmentAndOffsetFromPtr(const Expr14788 *E,14789 ASTContext14790 &Ctx) {14791 E = E->IgnoreParens();14792 switch (E->getStmtClass()) {14793 default:14794 break;14795 case Stmt::CStyleCastExprClass:14796 case Stmt::CXXStaticCastExprClass:14797 case Stmt::ImplicitCastExprClass: {14798 auto *CE = cast<CastExpr>(E);14799 const Expr *From = CE->getSubExpr();14800 switch (CE->getCastKind()) {14801 default:14802 break;14803 case CK_NoOp:14804 return getBaseAlignmentAndOffsetFromPtr(From, Ctx);14805 case CK_ArrayToPointerDecay:14806 return getBaseAlignmentAndOffsetFromLValue(From, Ctx);14807 case CK_UncheckedDerivedToBase:14808 case CK_DerivedToBase: {14809 auto P = getBaseAlignmentAndOffsetFromPtr(From, Ctx);14810 if (!P)14811 break;14812 return getDerivedToBaseAlignmentAndOffset(14813 CE, From->getType()->getPointeeType(), P->first, P->second, Ctx);14814 }14815 }14816 break;14817 }14818 case Stmt::CXXThisExprClass: {14819 auto *RD = E->getType()->getPointeeType()->getAsCXXRecordDecl();14820 CharUnits Alignment = Ctx.getASTRecordLayout(RD).getNonVirtualAlignment();14821 return std::make_pair(Alignment, CharUnits::Zero());14822 }14823 case Stmt::UnaryOperatorClass: {14824 auto *UO = cast<UnaryOperator>(E);14825 if (UO->getOpcode() == UO_AddrOf)14826 return getBaseAlignmentAndOffsetFromLValue(UO->getSubExpr(), Ctx);14827 break;14828 }14829 case Stmt::BinaryOperatorClass: {14830 auto *BO = cast<BinaryOperator>(E);14831 auto Opcode = BO->getOpcode();14832 switch (Opcode) {14833 default:14834 break;14835 case BO_Add:14836 case BO_Sub: {14837 const Expr *LHS = BO->getLHS(), *RHS = BO->getRHS();14838 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())14839 std::swap(LHS, RHS);14840 return getAlignmentAndOffsetFromBinAddOrSub(LHS, RHS, Opcode == BO_Sub,14841 Ctx);14842 }14843 case BO_Comma:14844 return getBaseAlignmentAndOffsetFromPtr(BO->getRHS(), Ctx);14845 }14846 break;14847 }14848 }14849 return std::nullopt;14850}14851 14852static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S) {14853 // See if we can compute the alignment of a VarDecl and an offset from it.14854 std::optional<std::pair<CharUnits, CharUnits>> P =14855 getBaseAlignmentAndOffsetFromPtr(E, S.Context);14856 14857 if (P)14858 return P->first.alignmentAtOffset(P->second);14859 14860 // If that failed, return the type's alignment.14861 return S.Context.getTypeAlignInChars(E->getType()->getPointeeType());14862}14863 14864void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {14865 // This is actually a lot of work to potentially be doing on every14866 // cast; don't do it if we're ignoring -Wcast_align (as is the default).14867 if (getDiagnostics().isIgnored(diag::warn_cast_align, TRange.getBegin()))14868 return;14869 14870 // Ignore dependent types.14871 if (T->isDependentType() || Op->getType()->isDependentType())14872 return;14873 14874 // Require that the destination be a pointer type.14875 const PointerType *DestPtr = T->getAs<PointerType>();14876 if (!DestPtr) return;14877 14878 // If the destination has alignment 1, we're done.14879 QualType DestPointee = DestPtr->getPointeeType();14880 if (DestPointee->isIncompleteType()) return;14881 CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee);14882 if (DestAlign.isOne()) return;14883 14884 // Require that the source be a pointer type.14885 const PointerType *SrcPtr = Op->getType()->getAs<PointerType>();14886 if (!SrcPtr) return;14887 QualType SrcPointee = SrcPtr->getPointeeType();14888 14889 // Explicitly allow casts from cv void*. We already implicitly14890 // allowed casts to cv void*, since they have alignment 1.14891 // Also allow casts involving incomplete types, which implicitly14892 // includes 'void'.14893 if (SrcPointee->isIncompleteType()) return;14894 14895 CharUnits SrcAlign = getPresumedAlignmentOfPointer(Op, *this);14896 14897 if (SrcAlign >= DestAlign) return;14898 14899 Diag(TRange.getBegin(), diag::warn_cast_align)14900 << Op->getType() << T14901 << static_cast<unsigned>(SrcAlign.getQuantity())14902 << static_cast<unsigned>(DestAlign.getQuantity())14903 << TRange << Op->getSourceRange();14904}14905 14906void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,14907 const ArraySubscriptExpr *ASE,14908 bool AllowOnePastEnd, bool IndexNegated) {14909 // Already diagnosed by the constant evaluator.14910 if (isConstantEvaluatedContext())14911 return;14912 14913 IndexExpr = IndexExpr->IgnoreParenImpCasts();14914 if (IndexExpr->isValueDependent())14915 return;14916 14917 const Type *EffectiveType =14918 BaseExpr->getType()->getPointeeOrArrayElementType();14919 BaseExpr = BaseExpr->IgnoreParenCasts();14920 const ConstantArrayType *ArrayTy =14921 Context.getAsConstantArrayType(BaseExpr->getType());14922 14923 LangOptions::StrictFlexArraysLevelKind14924 StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel();14925 14926 const Type *BaseType =14927 ArrayTy == nullptr ? nullptr : ArrayTy->getElementType().getTypePtr();14928 bool IsUnboundedArray =14929 BaseType == nullptr || BaseExpr->isFlexibleArrayMemberLike(14930 Context, StrictFlexArraysLevel,14931 /*IgnoreTemplateOrMacroSubstitution=*/true);14932 if (EffectiveType->isDependentType() ||14933 (!IsUnboundedArray && BaseType->isDependentType()))14934 return;14935 14936 Expr::EvalResult Result;14937 if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))14938 return;14939 14940 llvm::APSInt index = Result.Val.getInt();14941 if (IndexNegated) {14942 index.setIsUnsigned(false);14943 index = -index;14944 }14945 14946 if (IsUnboundedArray) {14947 if (EffectiveType->isFunctionType())14948 return;14949 if (index.isUnsigned() || !index.isNegative()) {14950 const auto &ASTC = getASTContext();14951 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(14952 EffectiveType->getCanonicalTypeInternal().getAddressSpace());14953 if (index.getBitWidth() < AddrBits)14954 index = index.zext(AddrBits);14955 std::optional<CharUnits> ElemCharUnits =14956 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);14957 // PR50741 - If EffectiveType has unknown size (e.g., if it's a void14958 // pointer) bounds-checking isn't meaningful.14959 if (!ElemCharUnits || ElemCharUnits->isZero())14960 return;14961 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());14962 // If index has more active bits than address space, we already know14963 // we have a bounds violation to warn about. Otherwise, compute14964 // address of (index + 1)th element, and warn about bounds violation14965 // only if that address exceeds address space.14966 if (index.getActiveBits() <= AddrBits) {14967 bool Overflow;14968 llvm::APInt Product(index);14969 Product += 1;14970 Product = Product.umul_ov(ElemBytes, Overflow);14971 if (!Overflow && Product.getActiveBits() <= AddrBits)14972 return;14973 }14974 14975 // Need to compute max possible elements in address space, since that14976 // is included in diag message.14977 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);14978 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));14979 MaxElems += 1;14980 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());14981 MaxElems = MaxElems.udiv(ElemBytes);14982 14983 unsigned DiagID =14984 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds14985 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;14986 14987 // Diag message shows element size in bits and in "bytes" (platform-14988 // dependent CharUnits)14989 DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,14990 PDiag(DiagID) << index << AddrBits14991 << (unsigned)ASTC.toBits(*ElemCharUnits)14992 << ElemBytes << MaxElems14993 << MaxElems.getZExtValue()14994 << IndexExpr->getSourceRange());14995 14996 const NamedDecl *ND = nullptr;14997 // Try harder to find a NamedDecl to point at in the note.14998 while (const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))14999 BaseExpr = ASE->getBase()->IgnoreParenCasts();15000 if (const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))15001 ND = DRE->getDecl();15002 if (const auto *ME = dyn_cast<MemberExpr>(BaseExpr))15003 ND = ME->getMemberDecl();15004 15005 if (ND)15006 DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr,15007 PDiag(diag::note_array_declared_here) << ND);15008 }15009 return;15010 }15011 15012 if (index.isUnsigned() || !index.isNegative()) {15013 // It is possible that the type of the base expression after15014 // IgnoreParenCasts is incomplete, even though the type of the base15015 // expression before IgnoreParenCasts is complete (see PR39746 for an15016 // example). In this case we have no information about whether the array15017 // access exceeds the array bounds. However we can still diagnose an array15018 // access which precedes the array bounds.15019 if (BaseType->isIncompleteType())15020 return;15021 15022 llvm::APInt size = ArrayTy->getSize();15023 15024 if (BaseType != EffectiveType) {15025 // Make sure we're comparing apples to apples when comparing index to15026 // size.15027 uint64_t ptrarith_typesize = Context.getTypeSize(EffectiveType);15028 uint64_t array_typesize = Context.getTypeSize(BaseType);15029 15030 // Handle ptrarith_typesize being zero, such as when casting to void*.15031 // Use the size in bits (what "getTypeSize()" returns) rather than bytes.15032 if (!ptrarith_typesize)15033 ptrarith_typesize = Context.getCharWidth();15034 15035 if (ptrarith_typesize != array_typesize) {15036 // There's a cast to a different size type involved.15037 uint64_t ratio = array_typesize / ptrarith_typesize;15038 15039 // TODO: Be smarter about handling cases where array_typesize is not a15040 // multiple of ptrarith_typesize.15041 if (ptrarith_typesize * ratio == array_typesize)15042 size *= llvm::APInt(size.getBitWidth(), ratio);15043 }15044 }15045 15046 if (size.getBitWidth() > index.getBitWidth())15047 index = index.zext(size.getBitWidth());15048 else if (size.getBitWidth() < index.getBitWidth())15049 size = size.zext(index.getBitWidth());15050 15051 // For array subscripting the index must be less than size, but for pointer15052 // arithmetic also allow the index (offset) to be equal to size since15053 // computing the next address after the end of the array is legal and15054 // commonly done e.g. in C++ iterators and range-based for loops.15055 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))15056 return;15057 15058 // Suppress the warning if the subscript expression (as identified by the15059 // ']' location) and the index expression are both from macro expansions15060 // within a system header.15061 if (ASE) {15062 SourceLocation RBracketLoc = SourceMgr.getSpellingLoc(15063 ASE->getRBracketLoc());15064 if (SourceMgr.isInSystemHeader(RBracketLoc)) {15065 SourceLocation IndexLoc =15066 SourceMgr.getSpellingLoc(IndexExpr->getBeginLoc());15067 if (SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))15068 return;15069 }15070 }15071 15072 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds15073 : diag::warn_ptr_arith_exceeds_bounds;15074 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;15075 QualType CastMsgTy = ASE ? ASE->getLHS()->getType() : QualType();15076 15077 DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,15078 PDiag(DiagID)15079 << index << ArrayTy->desugar() << CastMsg15080 << CastMsgTy << IndexExpr->getSourceRange());15081 } else {15082 unsigned DiagID = diag::warn_array_index_precedes_bounds;15083 if (!ASE) {15084 DiagID = diag::warn_ptr_arith_precedes_bounds;15085 if (index.isNegative()) index = -index;15086 }15087 15088 DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,15089 PDiag(DiagID) << index << IndexExpr->getSourceRange());15090 }15091 15092 const NamedDecl *ND = nullptr;15093 // Try harder to find a NamedDecl to point at in the note.15094 while (const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))15095 BaseExpr = ASE->getBase()->IgnoreParenCasts();15096 if (const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))15097 ND = DRE->getDecl();15098 if (const auto *ME = dyn_cast<MemberExpr>(BaseExpr))15099 ND = ME->getMemberDecl();15100 15101 if (ND)15102 DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr,15103 PDiag(diag::note_array_declared_here) << ND);15104}15105 15106void Sema::CheckArrayAccess(const Expr *expr) {15107 int AllowOnePastEnd = 0;15108 while (expr) {15109 expr = expr->IgnoreParenImpCasts();15110 switch (expr->getStmtClass()) {15111 case Stmt::ArraySubscriptExprClass: {15112 const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr);15113 CheckArrayAccess(ASE->getBase(), ASE->getIdx(), ASE,15114 AllowOnePastEnd > 0);15115 expr = ASE->getBase();15116 break;15117 }15118 case Stmt::MemberExprClass: {15119 expr = cast<MemberExpr>(expr)->getBase();15120 break;15121 }15122 case Stmt::ArraySectionExprClass: {15123 const ArraySectionExpr *ASE = cast<ArraySectionExpr>(expr);15124 // FIXME: We should probably be checking all of the elements to the15125 // 'length' here as well.15126 if (ASE->getLowerBound())15127 CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(),15128 /*ASE=*/nullptr, AllowOnePastEnd > 0);15129 return;15130 }15131 case Stmt::UnaryOperatorClass: {15132 // Only unwrap the * and & unary operators15133 const UnaryOperator *UO = cast<UnaryOperator>(expr);15134 expr = UO->getSubExpr();15135 switch (UO->getOpcode()) {15136 case UO_AddrOf:15137 AllowOnePastEnd++;15138 break;15139 case UO_Deref:15140 AllowOnePastEnd--;15141 break;15142 default:15143 return;15144 }15145 break;15146 }15147 case Stmt::ConditionalOperatorClass: {15148 const ConditionalOperator *cond = cast<ConditionalOperator>(expr);15149 if (const Expr *lhs = cond->getLHS())15150 CheckArrayAccess(lhs);15151 if (const Expr *rhs = cond->getRHS())15152 CheckArrayAccess(rhs);15153 return;15154 }15155 case Stmt::CXXOperatorCallExprClass: {15156 const auto *OCE = cast<CXXOperatorCallExpr>(expr);15157 for (const auto *Arg : OCE->arguments())15158 CheckArrayAccess(Arg);15159 return;15160 }15161 default:15162 return;15163 }15164 }15165}15166 15167static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc,15168 Expr *RHS, bool isProperty) {15169 // Check if RHS is an Objective-C object literal, which also can get15170 // immediately zapped in a weak reference. Note that we explicitly15171 // allow ObjCStringLiterals, since those are designed to never really die.15172 RHS = RHS->IgnoreParenImpCasts();15173 15174 // This enum needs to match with the 'select' in15175 // warn_objc_arc_literal_assign (off-by-1).15176 SemaObjC::ObjCLiteralKind Kind = S.ObjC().CheckLiteralKind(RHS);15177 if (Kind == SemaObjC::LK_String || Kind == SemaObjC::LK_None)15178 return false;15179 15180 S.Diag(Loc, diag::warn_arc_literal_assign)15181 << (unsigned) Kind15182 << (isProperty ? 0 : 1)15183 << RHS->getSourceRange();15184 15185 return true;15186}15187 15188static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc,15189 Qualifiers::ObjCLifetime LT,15190 Expr *RHS, bool isProperty) {15191 // Strip off any implicit cast added to get to the one ARC-specific.15192 while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) {15193 if (cast->getCastKind() == CK_ARCConsumeObject) {15194 S.Diag(Loc, diag::warn_arc_retained_assign)15195 << (LT == Qualifiers::OCL_ExplicitNone)15196 << (isProperty ? 0 : 1)15197 << RHS->getSourceRange();15198 return true;15199 }15200 RHS = cast->getSubExpr();15201 }15202 15203 if (LT == Qualifiers::OCL_Weak &&15204 checkUnsafeAssignLiteral(S, Loc, RHS, isProperty))15205 return true;15206 15207 return false;15208}15209 15210bool Sema::checkUnsafeAssigns(SourceLocation Loc,15211 QualType LHS, Expr *RHS) {15212 Qualifiers::ObjCLifetime LT = LHS.getObjCLifetime();15213 15214 if (LT != Qualifiers::OCL_Weak && LT != Qualifiers::OCL_ExplicitNone)15215 return false;15216 15217 if (checkUnsafeAssignObject(*this, Loc, LT, RHS, false))15218 return true;15219 15220 return false;15221}15222 15223void Sema::checkUnsafeExprAssigns(SourceLocation Loc,15224 Expr *LHS, Expr *RHS) {15225 QualType LHSType;15226 // PropertyRef on LHS type need be directly obtained from15227 // its declaration as it has a PseudoType.15228 ObjCPropertyRefExpr *PRE15229 = dyn_cast<ObjCPropertyRefExpr>(LHS->IgnoreParens());15230 if (PRE && !PRE->isImplicitProperty()) {15231 const ObjCPropertyDecl *PD = PRE->getExplicitProperty();15232 if (PD)15233 LHSType = PD->getType();15234 }15235 15236 if (LHSType.isNull())15237 LHSType = LHS->getType();15238 15239 Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime();15240 15241 if (LT == Qualifiers::OCL_Weak) {15242 if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))15243 getCurFunction()->markSafeWeakUse(LHS);15244 }15245 15246 if (checkUnsafeAssigns(Loc, LHSType, RHS))15247 return;15248 15249 // FIXME. Check for other life times.15250 if (LT != Qualifiers::OCL_None)15251 return;15252 15253 if (PRE) {15254 if (PRE->isImplicitProperty())15255 return;15256 const ObjCPropertyDecl *PD = PRE->getExplicitProperty();15257 if (!PD)15258 return;15259 15260 unsigned Attributes = PD->getPropertyAttributes();15261 if (Attributes & ObjCPropertyAttribute::kind_assign) {15262 // when 'assign' attribute was not explicitly specified15263 // by user, ignore it and rely on property type itself15264 // for lifetime info.15265 unsigned AsWrittenAttr = PD->getPropertyAttributesAsWritten();15266 if (!(AsWrittenAttr & ObjCPropertyAttribute::kind_assign) &&15267 LHSType->isObjCRetainableType())15268 return;15269 15270 while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) {15271 if (cast->getCastKind() == CK_ARCConsumeObject) {15272 Diag(Loc, diag::warn_arc_retained_property_assign)15273 << RHS->getSourceRange();15274 return;15275 }15276 RHS = cast->getSubExpr();15277 }15278 } else if (Attributes & ObjCPropertyAttribute::kind_weak) {15279 if (checkUnsafeAssignObject(*this, Loc, Qualifiers::OCL_Weak, RHS, true))15280 return;15281 }15282 }15283}15284 15285//===--- CHECK: Empty statement body (-Wempty-body) ---------------------===//15286 15287static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr,15288 SourceLocation StmtLoc,15289 const NullStmt *Body) {15290 // Do not warn if the body is a macro that expands to nothing, e.g:15291 //15292 // #define CALL(x)15293 // if (condition)15294 // CALL(0);15295 if (Body->hasLeadingEmptyMacro())15296 return false;15297 15298 // Get line numbers of statement and body.15299 bool StmtLineInvalid;15300 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,15301 &StmtLineInvalid);15302 if (StmtLineInvalid)15303 return false;15304 15305 bool BodyLineInvalid;15306 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->getSemiLoc(),15307 &BodyLineInvalid);15308 if (BodyLineInvalid)15309 return false;15310 15311 // Warn if null statement and body are on the same line.15312 if (StmtLine != BodyLine)15313 return false;15314 15315 return true;15316}15317 15318void Sema::DiagnoseEmptyStmtBody(SourceLocation StmtLoc,15319 const Stmt *Body,15320 unsigned DiagID) {15321 // Since this is a syntactic check, don't emit diagnostic for template15322 // instantiations, this just adds noise.15323 if (CurrentInstantiationScope)15324 return;15325 15326 // The body should be a null statement.15327 const NullStmt *NBody = dyn_cast<NullStmt>(Body);15328 if (!NBody)15329 return;15330 15331 // Do the usual checks.15332 if (!ShouldDiagnoseEmptyStmtBody(SourceMgr, StmtLoc, NBody))15333 return;15334 15335 Diag(NBody->getSemiLoc(), DiagID);15336 Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line);15337}15338 15339void Sema::DiagnoseEmptyLoopBody(const Stmt *S,15340 const Stmt *PossibleBody) {15341 assert(!CurrentInstantiationScope); // Ensured by caller15342 15343 SourceLocation StmtLoc;15344 const Stmt *Body;15345 unsigned DiagID;15346 if (const ForStmt *FS = dyn_cast<ForStmt>(S)) {15347 StmtLoc = FS->getRParenLoc();15348 Body = FS->getBody();15349 DiagID = diag::warn_empty_for_body;15350 } else if (const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {15351 StmtLoc = WS->getRParenLoc();15352 Body = WS->getBody();15353 DiagID = diag::warn_empty_while_body;15354 } else15355 return; // Neither `for' nor `while'.15356 15357 // The body should be a null statement.15358 const NullStmt *NBody = dyn_cast<NullStmt>(Body);15359 if (!NBody)15360 return;15361 15362 // Skip expensive checks if diagnostic is disabled.15363 if (Diags.isIgnored(DiagID, NBody->getSemiLoc()))15364 return;15365 15366 // Do the usual checks.15367 if (!ShouldDiagnoseEmptyStmtBody(SourceMgr, StmtLoc, NBody))15368 return;15369 15370 // `for(...);' and `while(...);' are popular idioms, so in order to keep15371 // noise level low, emit diagnostics only if for/while is followed by a15372 // CompoundStmt, e.g.:15373 // for (int i = 0; i < n; i++);15374 // {15375 // a(i);15376 // }15377 // or if for/while is followed by a statement with more indentation15378 // than for/while itself:15379 // for (int i = 0; i < n; i++);15380 // a(i);15381 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);15382 if (!ProbableTypo) {15383 bool BodyColInvalid;15384 unsigned BodyCol = SourceMgr.getPresumedColumnNumber(15385 PossibleBody->getBeginLoc(), &BodyColInvalid);15386 if (BodyColInvalid)15387 return;15388 15389 bool StmtColInvalid;15390 unsigned StmtCol =15391 SourceMgr.getPresumedColumnNumber(S->getBeginLoc(), &StmtColInvalid);15392 if (StmtColInvalid)15393 return;15394 15395 if (BodyCol > StmtCol)15396 ProbableTypo = true;15397 }15398 15399 if (ProbableTypo) {15400 Diag(NBody->getSemiLoc(), DiagID);15401 Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line);15402 }15403}15404 15405//===--- CHECK: Warn on self move with std::move. -------------------------===//15406 15407void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr,15408 SourceLocation OpLoc) {15409 if (Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))15410 return;15411 15412 if (inTemplateInstantiation())15413 return;15414 15415 // Strip parens and casts away.15416 LHSExpr = LHSExpr->IgnoreParenImpCasts();15417 RHSExpr = RHSExpr->IgnoreParenImpCasts();15418 15419 // Check for a call to std::move or for a static_cast<T&&>(..) to an xvalue15420 // which we can treat as an inlined std::move15421 if (const auto *CE = dyn_cast<CallExpr>(RHSExpr);15422 CE && CE->getNumArgs() == 1 && CE->isCallToStdMove())15423 RHSExpr = CE->getArg(0);15424 else if (const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);15425 CXXSCE && CXXSCE->isXValue())15426 RHSExpr = CXXSCE->getSubExpr();15427 else15428 return;15429 15430 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);15431 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);15432 15433 // Two DeclRefExpr's, check that the decls are the same.15434 if (LHSDeclRef && RHSDeclRef) {15435 if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl())15436 return;15437 if (LHSDeclRef->getDecl()->getCanonicalDecl() !=15438 RHSDeclRef->getDecl()->getCanonicalDecl())15439 return;15440 15441 auto D = Diag(OpLoc, diag::warn_self_move)15442 << LHSExpr->getType() << LHSExpr->getSourceRange()15443 << RHSExpr->getSourceRange();15444 if (const FieldDecl *F =15445 getSelfAssignmentClassMemberCandidate(RHSDeclRef->getDecl()))15446 D << 1 << F15447 << FixItHint::CreateInsertion(LHSDeclRef->getBeginLoc(), "this->");15448 else15449 D << 0;15450 return;15451 }15452 15453 // Member variables require a different approach to check for self moves.15454 // MemberExpr's are the same if every nested MemberExpr refers to the same15455 // Decl and that the base Expr's are DeclRefExpr's with the same Decl or15456 // the base Expr's are CXXThisExpr's.15457 const Expr *LHSBase = LHSExpr;15458 const Expr *RHSBase = RHSExpr;15459 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);15460 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);15461 if (!LHSME || !RHSME)15462 return;15463 15464 while (LHSME && RHSME) {15465 if (LHSME->getMemberDecl()->getCanonicalDecl() !=15466 RHSME->getMemberDecl()->getCanonicalDecl())15467 return;15468 15469 LHSBase = LHSME->getBase();15470 RHSBase = RHSME->getBase();15471 LHSME = dyn_cast<MemberExpr>(LHSBase);15472 RHSME = dyn_cast<MemberExpr>(RHSBase);15473 }15474 15475 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);15476 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);15477 if (LHSDeclRef && RHSDeclRef) {15478 if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl())15479 return;15480 if (LHSDeclRef->getDecl()->getCanonicalDecl() !=15481 RHSDeclRef->getDecl()->getCanonicalDecl())15482 return;15483 15484 Diag(OpLoc, diag::warn_self_move)15485 << LHSExpr->getType() << 0 << LHSExpr->getSourceRange()15486 << RHSExpr->getSourceRange();15487 return;15488 }15489 15490 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))15491 Diag(OpLoc, diag::warn_self_move)15492 << LHSExpr->getType() << 0 << LHSExpr->getSourceRange()15493 << RHSExpr->getSourceRange();15494}15495 15496//===--- Layout compatibility ----------------------------------------------//15497 15498static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2);15499 15500/// Check if two enumeration types are layout-compatible.15501static bool isLayoutCompatible(const ASTContext &C, const EnumDecl *ED1,15502 const EnumDecl *ED2) {15503 // C++11 [dcl.enum] p8:15504 // Two enumeration types are layout-compatible if they have the same15505 // underlying type.15506 return ED1->isComplete() && ED2->isComplete() &&15507 C.hasSameType(ED1->getIntegerType(), ED2->getIntegerType());15508}15509 15510/// Check if two fields are layout-compatible.15511/// Can be used on union members, which are exempt from alignment requirement15512/// of common initial sequence.15513static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1,15514 const FieldDecl *Field2,15515 bool AreUnionMembers = false) {15516#ifndef NDEBUG15517 CanQualType Field1Parent = C.getCanonicalTagType(Field1->getParent());15518 CanQualType Field2Parent = C.getCanonicalTagType(Field2->getParent());15519 assert(((Field1Parent->isStructureOrClassType() &&15520 Field2Parent->isStructureOrClassType()) ||15521 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&15522 "Can't evaluate layout compatibility between a struct field and a "15523 "union field.");15524 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||15525 (AreUnionMembers && Field1Parent->isUnionType())) &&15526 "AreUnionMembers should be 'true' for union fields (only).");15527#endif15528 15529 if (!isLayoutCompatible(C, Field1->getType(), Field2->getType()))15530 return false;15531 15532 if (Field1->isBitField() != Field2->isBitField())15533 return false;15534 15535 if (Field1->isBitField()) {15536 // Make sure that the bit-fields are the same length.15537 unsigned Bits1 = Field1->getBitWidthValue();15538 unsigned Bits2 = Field2->getBitWidthValue();15539 15540 if (Bits1 != Bits2)15541 return false;15542 }15543 15544 if (Field1->hasAttr<clang::NoUniqueAddressAttr>() ||15545 Field2->hasAttr<clang::NoUniqueAddressAttr>())15546 return false;15547 15548 if (!AreUnionMembers &&15549 Field1->getMaxAlignment() != Field2->getMaxAlignment())15550 return false;15551 15552 return true;15553}15554 15555/// Check if two standard-layout structs are layout-compatible.15556/// (C++11 [class.mem] p17)15557static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1,15558 const RecordDecl *RD2) {15559 // Get to the class where the fields are declared15560 if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))15561 RD1 = D1CXX->getStandardLayoutBaseWithFields();15562 15563 if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))15564 RD2 = D2CXX->getStandardLayoutBaseWithFields();15565 15566 // Check the fields.15567 return llvm::equal(RD1->fields(), RD2->fields(),15568 [&C](const FieldDecl *F1, const FieldDecl *F2) -> bool {15569 return isLayoutCompatible(C, F1, F2);15570 });15571}15572 15573/// Check if two standard-layout unions are layout-compatible.15574/// (C++11 [class.mem] p18)15575static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1,15576 const RecordDecl *RD2) {15577 llvm::SmallPtrSet<const FieldDecl *, 8> UnmatchedFields(llvm::from_range,15578 RD2->fields());15579 15580 for (auto *Field1 : RD1->fields()) {15581 auto I = UnmatchedFields.begin();15582 auto E = UnmatchedFields.end();15583 15584 for ( ; I != E; ++I) {15585 if (isLayoutCompatible(C, Field1, *I, /*IsUnionMember=*/true)) {15586 bool Result = UnmatchedFields.erase(*I);15587 (void) Result;15588 assert(Result);15589 break;15590 }15591 }15592 if (I == E)15593 return false;15594 }15595 15596 return UnmatchedFields.empty();15597}15598 15599static bool isLayoutCompatible(const ASTContext &C, const RecordDecl *RD1,15600 const RecordDecl *RD2) {15601 if (RD1->isUnion() != RD2->isUnion())15602 return false;15603 15604 if (RD1->isUnion())15605 return isLayoutCompatibleUnion(C, RD1, RD2);15606 else15607 return isLayoutCompatibleStruct(C, RD1, RD2);15608}15609 15610/// Check if two types are layout-compatible in C++11 sense.15611static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) {15612 if (T1.isNull() || T2.isNull())15613 return false;15614 15615 // C++20 [basic.types] p11:15616 // Two types cv1 T1 and cv2 T2 are layout-compatible types15617 // if T1 and T2 are the same type, layout-compatible enumerations (9.7.1),15618 // or layout-compatible standard-layout class types (11.4).15619 T1 = T1.getCanonicalType().getUnqualifiedType();15620 T2 = T2.getCanonicalType().getUnqualifiedType();15621 15622 if (C.hasSameType(T1, T2))15623 return true;15624 15625 const Type::TypeClass TC1 = T1->getTypeClass();15626 const Type::TypeClass TC2 = T2->getTypeClass();15627 15628 if (TC1 != TC2)15629 return false;15630 15631 if (TC1 == Type::Enum)15632 return isLayoutCompatible(C, T1->castAsEnumDecl(), T2->castAsEnumDecl());15633 if (TC1 == Type::Record) {15634 if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType())15635 return false;15636 15637 return isLayoutCompatible(C, T1->castAsRecordDecl(),15638 T2->castAsRecordDecl());15639 }15640 15641 return false;15642}15643 15644bool Sema::IsLayoutCompatible(QualType T1, QualType T2) const {15645 return isLayoutCompatible(getASTContext(), T1, T2);15646}15647 15648//===-------------- Pointer interconvertibility ----------------------------//15649 15650bool Sema::IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base,15651 const TypeSourceInfo *Derived) {15652 QualType BaseT = Base->getType()->getCanonicalTypeUnqualified();15653 QualType DerivedT = Derived->getType()->getCanonicalTypeUnqualified();15654 15655 if (BaseT->isStructureOrClassType() && DerivedT->isStructureOrClassType() &&15656 getASTContext().hasSameType(BaseT, DerivedT))15657 return true;15658 15659 if (!IsDerivedFrom(Derived->getTypeLoc().getBeginLoc(), DerivedT, BaseT))15660 return false;15661 15662 // Per [basic.compound]/4.3, containing object has to be standard-layout.15663 if (DerivedT->getAsCXXRecordDecl()->isStandardLayout())15664 return true;15665 15666 return false;15667}15668 15669//===--- CHECK: pointer_with_type_tag attribute: datatypes should match ----//15670 15671/// Given a type tag expression find the type tag itself.15672///15673/// \param TypeExpr Type tag expression, as it appears in user's code.15674///15675/// \param VD Declaration of an identifier that appears in a type tag.15676///15677/// \param MagicValue Type tag magic value.15678///15679/// \param isConstantEvaluated whether the evalaution should be performed in15680 15681/// constant context.15682static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx,15683 const ValueDecl **VD, uint64_t *MagicValue,15684 bool isConstantEvaluated) {15685 while(true) {15686 if (!TypeExpr)15687 return false;15688 15689 TypeExpr = TypeExpr->IgnoreParenImpCasts()->IgnoreParenCasts();15690 15691 switch (TypeExpr->getStmtClass()) {15692 case Stmt::UnaryOperatorClass: {15693 const UnaryOperator *UO = cast<UnaryOperator>(TypeExpr);15694 if (UO->getOpcode() == UO_AddrOf || UO->getOpcode() == UO_Deref) {15695 TypeExpr = UO->getSubExpr();15696 continue;15697 }15698 return false;15699 }15700 15701 case Stmt::DeclRefExprClass: {15702 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);15703 *VD = DRE->getDecl();15704 return true;15705 }15706 15707 case Stmt::IntegerLiteralClass: {15708 const IntegerLiteral *IL = cast<IntegerLiteral>(TypeExpr);15709 llvm::APInt MagicValueAPInt = IL->getValue();15710 if (MagicValueAPInt.getActiveBits() <= 64) {15711 *MagicValue = MagicValueAPInt.getZExtValue();15712 return true;15713 } else15714 return false;15715 }15716 15717 case Stmt::BinaryConditionalOperatorClass:15718 case Stmt::ConditionalOperatorClass: {15719 const AbstractConditionalOperator *ACO =15720 cast<AbstractConditionalOperator>(TypeExpr);15721 bool Result;15722 if (ACO->getCond()->EvaluateAsBooleanCondition(Result, Ctx,15723 isConstantEvaluated)) {15724 if (Result)15725 TypeExpr = ACO->getTrueExpr();15726 else15727 TypeExpr = ACO->getFalseExpr();15728 continue;15729 }15730 return false;15731 }15732 15733 case Stmt::BinaryOperatorClass: {15734 const BinaryOperator *BO = cast<BinaryOperator>(TypeExpr);15735 if (BO->getOpcode() == BO_Comma) {15736 TypeExpr = BO->getRHS();15737 continue;15738 }15739 return false;15740 }15741 15742 default:15743 return false;15744 }15745 }15746}15747 15748/// Retrieve the C type corresponding to type tag TypeExpr.15749///15750/// \param TypeExpr Expression that specifies a type tag.15751///15752/// \param MagicValues Registered magic values.15753///15754/// \param FoundWrongKind Set to true if a type tag was found, but of a wrong15755/// kind.15756///15757/// \param TypeInfo Information about the corresponding C type.15758///15759/// \param isConstantEvaluated whether the evalaution should be performed in15760/// constant context.15761///15762/// \returns true if the corresponding C type was found.15763static bool GetMatchingCType(15764 const IdentifierInfo *ArgumentKind, const Expr *TypeExpr,15765 const ASTContext &Ctx,15766 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>15767 *MagicValues,15768 bool &FoundWrongKind, Sema::TypeTagData &TypeInfo,15769 bool isConstantEvaluated) {15770 FoundWrongKind = false;15771 15772 // Variable declaration that has type_tag_for_datatype attribute.15773 const ValueDecl *VD = nullptr;15774 15775 uint64_t MagicValue;15776 15777 if (!FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))15778 return false;15779 15780 if (VD) {15781 if (TypeTagForDatatypeAttr *I = VD->getAttr<TypeTagForDatatypeAttr>()) {15782 if (I->getArgumentKind() != ArgumentKind) {15783 FoundWrongKind = true;15784 return false;15785 }15786 TypeInfo.Type = I->getMatchingCType();15787 TypeInfo.LayoutCompatible = I->getLayoutCompatible();15788 TypeInfo.MustBeNull = I->getMustBeNull();15789 return true;15790 }15791 return false;15792 }15793 15794 if (!MagicValues)15795 return false;15796 15797 llvm::DenseMap<Sema::TypeTagMagicValue,15798 Sema::TypeTagData>::const_iterator I =15799 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));15800 if (I == MagicValues->end())15801 return false;15802 15803 TypeInfo = I->second;15804 return true;15805}15806 15807void Sema::RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,15808 uint64_t MagicValue, QualType Type,15809 bool LayoutCompatible,15810 bool MustBeNull) {15811 if (!TypeTagForDatatypeMagicValues)15812 TypeTagForDatatypeMagicValues.reset(15813 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);15814 15815 TypeTagMagicValue Magic(ArgumentKind, MagicValue);15816 (*TypeTagForDatatypeMagicValues)[Magic] =15817 TypeTagData(Type, LayoutCompatible, MustBeNull);15818}15819 15820static bool IsSameCharType(QualType T1, QualType T2) {15821 const BuiltinType *BT1 = T1->getAs<BuiltinType>();15822 if (!BT1)15823 return false;15824 15825 const BuiltinType *BT2 = T2->getAs<BuiltinType>();15826 if (!BT2)15827 return false;15828 15829 BuiltinType::Kind T1Kind = BT1->getKind();15830 BuiltinType::Kind T2Kind = BT2->getKind();15831 15832 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||15833 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||15834 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||15835 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);15836}15837 15838void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,15839 const ArrayRef<const Expr *> ExprArgs,15840 SourceLocation CallSiteLoc) {15841 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();15842 bool IsPointerAttr = Attr->getIsPointer();15843 15844 // Retrieve the argument representing the 'type_tag'.15845 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();15846 if (TypeTagIdxAST >= ExprArgs.size()) {15847 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)15848 << 0 << Attr->getTypeTagIdx().getSourceIndex();15849 return;15850 }15851 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];15852 bool FoundWrongKind;15853 TypeTagData TypeInfo;15854 if (!GetMatchingCType(ArgumentKind, TypeTagExpr, Context,15855 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,15856 TypeInfo, isConstantEvaluatedContext())) {15857 if (FoundWrongKind)15858 Diag(TypeTagExpr->getExprLoc(),15859 diag::warn_type_tag_for_datatype_wrong_kind)15860 << TypeTagExpr->getSourceRange();15861 return;15862 }15863 15864 // Retrieve the argument representing the 'arg_idx'.15865 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();15866 if (ArgumentIdxAST >= ExprArgs.size()) {15867 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)15868 << 1 << Attr->getArgumentIdx().getSourceIndex();15869 return;15870 }15871 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];15872 if (IsPointerAttr) {15873 // Skip implicit cast of pointer to `void *' (as a function argument).15874 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))15875 if (ICE->getType()->isVoidPointerType() &&15876 ICE->getCastKind() == CK_BitCast)15877 ArgumentExpr = ICE->getSubExpr();15878 }15879 QualType ArgumentType = ArgumentExpr->getType();15880 15881 // Passing a `void*' pointer shouldn't trigger a warning.15882 if (IsPointerAttr && ArgumentType->isVoidPointerType())15883 return;15884 15885 if (TypeInfo.MustBeNull) {15886 // Type tag with matching void type requires a null pointer.15887 if (!ArgumentExpr->isNullPointerConstant(Context,15888 Expr::NPC_ValueDependentIsNotNull)) {15889 Diag(ArgumentExpr->getExprLoc(),15890 diag::warn_type_safety_null_pointer_required)15891 << ArgumentKind->getName()15892 << ArgumentExpr->getSourceRange()15893 << TypeTagExpr->getSourceRange();15894 }15895 return;15896 }15897 15898 QualType RequiredType = TypeInfo.Type;15899 if (IsPointerAttr)15900 RequiredType = Context.getPointerType(RequiredType);15901 15902 bool mismatch = false;15903 if (!TypeInfo.LayoutCompatible) {15904 mismatch = !Context.hasSameType(ArgumentType, RequiredType);15905 15906 // C++11 [basic.fundamental] p1:15907 // Plain char, signed char, and unsigned char are three distinct types.15908 //15909 // But we treat plain `char' as equivalent to `signed char' or `unsigned15910 // char' depending on the current char signedness mode.15911 if (mismatch)15912 if ((IsPointerAttr && IsSameCharType(ArgumentType->getPointeeType(),15913 RequiredType->getPointeeType())) ||15914 (!IsPointerAttr && IsSameCharType(ArgumentType, RequiredType)))15915 mismatch = false;15916 } else15917 if (IsPointerAttr)15918 mismatch = !isLayoutCompatible(Context,15919 ArgumentType->getPointeeType(),15920 RequiredType->getPointeeType());15921 else15922 mismatch = !isLayoutCompatible(Context, ArgumentType, RequiredType);15923 15924 if (mismatch)15925 Diag(ArgumentExpr->getExprLoc(), diag::warn_type_safety_type_mismatch)15926 << ArgumentType << ArgumentKind15927 << TypeInfo.LayoutCompatible << RequiredType15928 << ArgumentExpr->getSourceRange()15929 << TypeTagExpr->getSourceRange();15930}15931 15932void Sema::AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD,15933 CharUnits Alignment) {15934 currentEvaluationContext().MisalignedMembers.emplace_back(E, RD, MD,15935 Alignment);15936}15937 15938void Sema::DiagnoseMisalignedMembers() {15939 for (MisalignedMember &m : currentEvaluationContext().MisalignedMembers) {15940 const NamedDecl *ND = m.RD;15941 if (ND->getName().empty()) {15942 if (const TypedefNameDecl *TD = m.RD->getTypedefNameForAnonDecl())15943 ND = TD;15944 }15945 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)15946 << m.MD << ND << m.E->getSourceRange();15947 }15948 currentEvaluationContext().MisalignedMembers.clear();15949}15950 15951void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) {15952 E = E->IgnoreParens();15953 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())15954 return;15955 if (isa<UnaryOperator>(E) &&15956 cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf) {15957 auto *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();15958 if (isa<MemberExpr>(Op)) {15959 auto &MisalignedMembersForExpr =15960 currentEvaluationContext().MisalignedMembers;15961 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));15962 if (MA != MisalignedMembersForExpr.end() &&15963 (T->isDependentType() || T->isIntegerType() ||15964 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||15965 Context.getTypeAlignInChars(15966 T->getPointeeType()) <= MA->Alignment))))15967 MisalignedMembersForExpr.erase(MA);15968 }15969 }15970}15971 15972void Sema::RefersToMemberWithReducedAlignment(15973 Expr *E,15974 llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)>15975 Action) {15976 const auto *ME = dyn_cast<MemberExpr>(E);15977 if (!ME)15978 return;15979 15980 // No need to check expressions with an __unaligned-qualified type.15981 if (E->getType().getQualifiers().hasUnaligned())15982 return;15983 15984 // For a chain of MemberExpr like "a.b.c.d" this list15985 // will keep FieldDecl's like [d, c, b].15986 SmallVector<FieldDecl *, 4> ReverseMemberChain;15987 const MemberExpr *TopME = nullptr;15988 bool AnyIsPacked = false;15989 do {15990 QualType BaseType = ME->getBase()->getType();15991 if (BaseType->isDependentType())15992 return;15993 if (ME->isArrow())15994 BaseType = BaseType->getPointeeType();15995 auto *RD = BaseType->castAsRecordDecl();15996 if (RD->isInvalidDecl())15997 return;15998 15999 ValueDecl *MD = ME->getMemberDecl();16000 auto *FD = dyn_cast<FieldDecl>(MD);16001 // We do not care about non-data members.16002 if (!FD || FD->isInvalidDecl())16003 return;16004 16005 AnyIsPacked =16006 AnyIsPacked || (RD->hasAttr<PackedAttr>() || MD->hasAttr<PackedAttr>());16007 ReverseMemberChain.push_back(FD);16008 16009 TopME = ME;16010 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());16011 } while (ME);16012 assert(TopME && "We did not compute a topmost MemberExpr!");16013 16014 // Not the scope of this diagnostic.16015 if (!AnyIsPacked)16016 return;16017 16018 const Expr *TopBase = TopME->getBase()->IgnoreParenImpCasts();16019 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);16020 // TODO: The innermost base of the member expression may be too complicated.16021 // For now, just disregard these cases. This is left for future16022 // improvement.16023 if (!DRE && !isa<CXXThisExpr>(TopBase))16024 return;16025 16026 // Alignment expected by the whole expression.16027 CharUnits ExpectedAlignment = Context.getTypeAlignInChars(E->getType());16028 16029 // No need to do anything else with this case.16030 if (ExpectedAlignment.isOne())16031 return;16032 16033 // Synthesize offset of the whole access.16034 CharUnits Offset;16035 for (const FieldDecl *FD : llvm::reverse(ReverseMemberChain))16036 Offset += Context.toCharUnitsFromBits(Context.getFieldOffset(FD));16037 16038 // Compute the CompleteObjectAlignment as the alignment of the whole chain.16039 CharUnits CompleteObjectAlignment = Context.getTypeAlignInChars(16040 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));16041 16042 // The base expression of the innermost MemberExpr may give16043 // stronger guarantees than the class containing the member.16044 if (DRE && !TopME->isArrow()) {16045 const ValueDecl *VD = DRE->getDecl();16046 if (!VD->getType()->isReferenceType())16047 CompleteObjectAlignment =16048 std::max(CompleteObjectAlignment, Context.getDeclAlign(VD));16049 }16050 16051 // Check if the synthesized offset fulfills the alignment.16052 if (!Offset.isMultipleOf(ExpectedAlignment) ||16053 // It may fulfill the offset it but the effective alignment may still be16054 // lower than the expected expression alignment.16055 CompleteObjectAlignment < ExpectedAlignment) {16056 // If this happens, we want to determine a sensible culprit of this.16057 // Intuitively, watching the chain of member expressions from right to16058 // left, we start with the required alignment (as required by the field16059 // type) but some packed attribute in that chain has reduced the alignment.16060 // It may happen that another packed structure increases it again. But if16061 // we are here such increase has not been enough. So pointing the first16062 // FieldDecl that either is packed or else its RecordDecl is,16063 // seems reasonable.16064 FieldDecl *FD = nullptr;16065 CharUnits Alignment;16066 for (FieldDecl *FDI : ReverseMemberChain) {16067 if (FDI->hasAttr<PackedAttr>() ||16068 FDI->getParent()->hasAttr<PackedAttr>()) {16069 FD = FDI;16070 Alignment = std::min(Context.getTypeAlignInChars(FD->getType()),16071 Context.getTypeAlignInChars(16072 Context.getCanonicalTagType(FD->getParent())));16073 break;16074 }16075 }16076 assert(FD && "We did not find a packed FieldDecl!");16077 Action(E, FD->getParent(), FD, Alignment);16078 }16079}16080 16081void Sema::CheckAddressOfPackedMember(Expr *rhs) {16082 using namespace std::placeholders;16083 16084 RefersToMemberWithReducedAlignment(16085 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*this), _1,16086 _2, _3, _4));16087}16088 16089bool Sema::PrepareBuiltinElementwiseMathOneArgCall(16090 CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr) {16091 if (checkArgCount(TheCall, 1))16092 return true;16093 16094 ExprResult A = BuiltinVectorMathConversions(*this, TheCall->getArg(0));16095 if (A.isInvalid())16096 return true;16097 16098 TheCall->setArg(0, A.get());16099 QualType TyA = A.get()->getType();16100 16101 if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA,16102 ArgTyRestr, 1))16103 return true;16104 16105 TheCall->setType(TyA);16106 return false;16107}16108 16109bool Sema::BuiltinElementwiseMath(CallExpr *TheCall,16110 EltwiseBuiltinArgTyRestriction ArgTyRestr) {16111 if (auto Res = BuiltinVectorMath(TheCall, ArgTyRestr); Res.has_value()) {16112 TheCall->setType(*Res);16113 return false;16114 }16115 return true;16116}16117 16118bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {16119 std::optional<QualType> Res = BuiltinVectorMath(TheCall);16120 if (!Res)16121 return true;16122 16123 if (auto *VecTy0 = (*Res)->getAs<VectorType>())16124 TheCall->setType(VecTy0->getElementType());16125 else16126 TheCall->setType(*Res);16127 16128 return false;16129}16130 16131static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS,16132 SourceLocation Loc) {16133 QualType L = LHS->getEnumCoercedType(S.Context),16134 R = RHS->getEnumCoercedType(S.Context);16135 if (L->isUnscopedEnumerationType() && R->isUnscopedEnumerationType() &&16136 !S.Context.hasSameUnqualifiedType(L, R)) {16137 return S.Diag(Loc, diag::err_conv_mixed_enum_types)16138 << LHS->getSourceRange() << RHS->getSourceRange()16139 << /*Arithmetic Between*/ 0 << L << R;16140 }16141 return false;16142}16143 16144/// Check if all arguments have the same type. If the types don't match, emit an16145/// error message and return true. Otherwise return false.16146///16147/// For scalars we directly compare their unqualified types. But even if we16148/// compare unqualified vector types, a difference in qualifiers in the element16149/// types can make the vector types be considered not equal. For example,16150/// vector of 4 'const float' values vs vector of 4 'float' values.16151/// So we compare unqualified types of their elements and number of elements.16152static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef,16153 ArrayRef<Expr *> Args) {16154 assert(!Args.empty() && "Should have at least one argument.");16155 16156 Expr *Arg0 = Args.front();16157 QualType Ty0 = Arg0->getType();16158 16159 auto EmitError = [&](Expr *ArgI) {16160 SemaRef.Diag(Arg0->getBeginLoc(),16161 diag::err_typecheck_call_different_arg_types)16162 << Arg0->getType() << ArgI->getType();16163 };16164 16165 // Compare scalar types.16166 if (!Ty0->isVectorType()) {16167 for (Expr *ArgI : Args.drop_front())16168 if (!SemaRef.Context.hasSameUnqualifiedType(Ty0, ArgI->getType())) {16169 EmitError(ArgI);16170 return true;16171 }16172 16173 return false;16174 }16175 16176 // Compare vector types.16177 const auto *Vec0 = Ty0->castAs<VectorType>();16178 for (Expr *ArgI : Args.drop_front()) {16179 const auto *VecI = ArgI->getType()->getAs<VectorType>();16180 if (!VecI ||16181 !SemaRef.Context.hasSameUnqualifiedType(Vec0->getElementType(),16182 VecI->getElementType()) ||16183 Vec0->getNumElements() != VecI->getNumElements()) {16184 EmitError(ArgI);16185 return true;16186 }16187 }16188 16189 return false;16190}16191 16192std::optional<QualType>16193Sema::BuiltinVectorMath(CallExpr *TheCall,16194 EltwiseBuiltinArgTyRestriction ArgTyRestr) {16195 if (checkArgCount(TheCall, 2))16196 return std::nullopt;16197 16198 if (checkBuiltinVectorMathMixedEnums(16199 *this, TheCall->getArg(0), TheCall->getArg(1), TheCall->getExprLoc()))16200 return std::nullopt;16201 16202 Expr *Args[2];16203 for (int I = 0; I < 2; ++I) {16204 ExprResult Converted =16205 BuiltinVectorMathConversions(*this, TheCall->getArg(I));16206 if (Converted.isInvalid())16207 return std::nullopt;16208 Args[I] = Converted.get();16209 }16210 16211 SourceLocation LocA = Args[0]->getBeginLoc();16212 QualType TyA = Args[0]->getType();16213 16214 if (checkMathBuiltinElementType(*this, LocA, TyA, ArgTyRestr, 1))16215 return std::nullopt;16216 16217 if (checkBuiltinVectorMathArgTypes(*this, Args))16218 return std::nullopt;16219 16220 TheCall->setArg(0, Args[0]);16221 TheCall->setArg(1, Args[1]);16222 return TyA;16223}16224 16225bool Sema::BuiltinElementwiseTernaryMath(16226 CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr) {16227 if (checkArgCount(TheCall, 3))16228 return true;16229 16230 SourceLocation Loc = TheCall->getExprLoc();16231 if (checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(0),16232 TheCall->getArg(1), Loc) ||16233 checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(1),16234 TheCall->getArg(2), Loc))16235 return true;16236 16237 Expr *Args[3];16238 for (int I = 0; I < 3; ++I) {16239 ExprResult Converted =16240 BuiltinVectorMathConversions(*this, TheCall->getArg(I));16241 if (Converted.isInvalid())16242 return true;16243 Args[I] = Converted.get();16244 }16245 16246 int ArgOrdinal = 1;16247 for (Expr *Arg : Args) {16248 if (checkMathBuiltinElementType(*this, Arg->getBeginLoc(), Arg->getType(),16249 ArgTyRestr, ArgOrdinal++))16250 return true;16251 }16252 16253 if (checkBuiltinVectorMathArgTypes(*this, Args))16254 return true;16255 16256 for (int I = 0; I < 3; ++I)16257 TheCall->setArg(I, Args[I]);16258 16259 TheCall->setType(Args[0]->getType());16260 return false;16261}16262 16263bool Sema::PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall) {16264 if (checkArgCount(TheCall, 1))16265 return true;16266 16267 ExprResult A = UsualUnaryConversions(TheCall->getArg(0));16268 if (A.isInvalid())16269 return true;16270 16271 TheCall->setArg(0, A.get());16272 return false;16273}16274 16275bool Sema::BuiltinNonDeterministicValue(CallExpr *TheCall) {16276 if (checkArgCount(TheCall, 1))16277 return true;16278 16279 ExprResult Arg = TheCall->getArg(0);16280 QualType TyArg = Arg.get()->getType();16281 16282 if (!TyArg->isBuiltinType() && !TyArg->isVectorType())16283 return Diag(TheCall->getArg(0)->getBeginLoc(),16284 diag::err_builtin_invalid_arg_type)16285 << 1 << /* vector */ 2 << /* integer */ 1 << /* fp */ 1 << TyArg;16286 16287 TheCall->setType(TyArg);16288 return false;16289}16290 16291ExprResult Sema::BuiltinMatrixTranspose(CallExpr *TheCall,16292 ExprResult CallResult) {16293 if (checkArgCount(TheCall, 1))16294 return ExprError();16295 16296 ExprResult MatrixArg = DefaultLvalueConversion(TheCall->getArg(0));16297 if (MatrixArg.isInvalid())16298 return MatrixArg;16299 Expr *Matrix = MatrixArg.get();16300 16301 auto *MType = Matrix->getType()->getAs<ConstantMatrixType>();16302 if (!MType) {16303 Diag(Matrix->getBeginLoc(), diag::err_builtin_invalid_arg_type)16304 << 1 << /* matrix */ 3 << /* no int */ 0 << /* no fp */ 016305 << Matrix->getType();16306 return ExprError();16307 }16308 16309 // Create returned matrix type by swapping rows and columns of the argument16310 // matrix type.16311 QualType ResultType = Context.getConstantMatrixType(16312 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());16313 16314 // Change the return type to the type of the returned matrix.16315 TheCall->setType(ResultType);16316 16317 // Update call argument to use the possibly converted matrix argument.16318 TheCall->setArg(0, Matrix);16319 return CallResult;16320}16321 16322// Get and verify the matrix dimensions.16323static std::optional<unsigned>16324getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S) {16325 std::optional<llvm::APSInt> Value = Expr->getIntegerConstantExpr(S.Context);16326 if (!Value) {16327 S.Diag(Expr->getBeginLoc(), diag::err_builtin_matrix_scalar_unsigned_arg)16328 << Name;16329 return {};16330 }16331 uint64_t Dim = Value->getZExtValue();16332 if (Dim == 0 || Dim > S.Context.getLangOpts().MaxMatrixDimension) {16333 S.Diag(Expr->getBeginLoc(), diag::err_builtin_matrix_invalid_dimension)16334 << Name << S.Context.getLangOpts().MaxMatrixDimension;16335 return {};16336 }16337 return Dim;16338}16339 16340ExprResult Sema::BuiltinMatrixColumnMajorLoad(CallExpr *TheCall,16341 ExprResult CallResult) {16342 if (!getLangOpts().MatrixTypes) {16343 Diag(TheCall->getBeginLoc(), diag::err_builtin_matrix_disabled);16344 return ExprError();16345 }16346 16347 if (checkArgCount(TheCall, 4))16348 return ExprError();16349 16350 unsigned PtrArgIdx = 0;16351 Expr *PtrExpr = TheCall->getArg(PtrArgIdx);16352 Expr *RowsExpr = TheCall->getArg(1);16353 Expr *ColumnsExpr = TheCall->getArg(2);16354 Expr *StrideExpr = TheCall->getArg(3);16355 16356 bool ArgError = false;16357 16358 // Check pointer argument.16359 {16360 ExprResult PtrConv = DefaultFunctionArrayLvalueConversion(PtrExpr);16361 if (PtrConv.isInvalid())16362 return PtrConv;16363 PtrExpr = PtrConv.get();16364 TheCall->setArg(0, PtrExpr);16365 if (PtrExpr->isTypeDependent()) {16366 TheCall->setType(Context.DependentTy);16367 return TheCall;16368 }16369 }16370 16371 auto *PtrTy = PtrExpr->getType()->getAs<PointerType>();16372 QualType ElementTy;16373 if (!PtrTy) {16374 Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)16375 << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 5 << /* no fp */ 016376 << PtrExpr->getType();16377 ArgError = true;16378 } else {16379 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();16380 16381 if (!ConstantMatrixType::isValidElementType(ElementTy)) {16382 Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)16383 << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 516384 << /* no fp */ 0 << PtrExpr->getType();16385 ArgError = true;16386 }16387 }16388 16389 // Apply default Lvalue conversions and convert the expression to size_t.16390 auto ApplyArgumentConversions = [this](Expr *E) {16391 ExprResult Conv = DefaultLvalueConversion(E);16392 if (Conv.isInvalid())16393 return Conv;16394 16395 return tryConvertExprToType(Conv.get(), Context.getSizeType());16396 };16397 16398 // Apply conversion to row and column expressions.16399 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);16400 if (!RowsConv.isInvalid()) {16401 RowsExpr = RowsConv.get();16402 TheCall->setArg(1, RowsExpr);16403 } else16404 RowsExpr = nullptr;16405 16406 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);16407 if (!ColumnsConv.isInvalid()) {16408 ColumnsExpr = ColumnsConv.get();16409 TheCall->setArg(2, ColumnsExpr);16410 } else16411 ColumnsExpr = nullptr;16412 16413 // If any part of the result matrix type is still pending, just use16414 // Context.DependentTy, until all parts are resolved.16415 if ((RowsExpr && RowsExpr->isTypeDependent()) ||16416 (ColumnsExpr && ColumnsExpr->isTypeDependent())) {16417 TheCall->setType(Context.DependentTy);16418 return CallResult;16419 }16420 16421 // Check row and column dimensions.16422 std::optional<unsigned> MaybeRows;16423 if (RowsExpr)16424 MaybeRows = getAndVerifyMatrixDimension(RowsExpr, "row", *this);16425 16426 std::optional<unsigned> MaybeColumns;16427 if (ColumnsExpr)16428 MaybeColumns = getAndVerifyMatrixDimension(ColumnsExpr, "column", *this);16429 16430 // Check stride argument.16431 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);16432 if (StrideConv.isInvalid())16433 return ExprError();16434 StrideExpr = StrideConv.get();16435 TheCall->setArg(3, StrideExpr);16436 16437 if (MaybeRows) {16438 if (std::optional<llvm::APSInt> Value =16439 StrideExpr->getIntegerConstantExpr(Context)) {16440 uint64_t Stride = Value->getZExtValue();16441 if (Stride < *MaybeRows) {16442 Diag(StrideExpr->getBeginLoc(),16443 diag::err_builtin_matrix_stride_too_small);16444 ArgError = true;16445 }16446 }16447 }16448 16449 if (ArgError || !MaybeRows || !MaybeColumns)16450 return ExprError();16451 16452 TheCall->setType(16453 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));16454 return CallResult;16455}16456 16457ExprResult Sema::BuiltinMatrixColumnMajorStore(CallExpr *TheCall,16458 ExprResult CallResult) {16459 if (checkArgCount(TheCall, 3))16460 return ExprError();16461 16462 unsigned PtrArgIdx = 1;16463 Expr *MatrixExpr = TheCall->getArg(0);16464 Expr *PtrExpr = TheCall->getArg(PtrArgIdx);16465 Expr *StrideExpr = TheCall->getArg(2);16466 16467 bool ArgError = false;16468 16469 {16470 ExprResult MatrixConv = DefaultLvalueConversion(MatrixExpr);16471 if (MatrixConv.isInvalid())16472 return MatrixConv;16473 MatrixExpr = MatrixConv.get();16474 TheCall->setArg(0, MatrixExpr);16475 }16476 if (MatrixExpr->isTypeDependent()) {16477 TheCall->setType(Context.DependentTy);16478 return TheCall;16479 }16480 16481 auto *MatrixTy = MatrixExpr->getType()->getAs<ConstantMatrixType>();16482 if (!MatrixTy) {16483 Diag(MatrixExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)16484 << 1 << /* matrix ty */ 3 << 0 << 0 << MatrixExpr->getType();16485 ArgError = true;16486 }16487 16488 {16489 ExprResult PtrConv = DefaultFunctionArrayLvalueConversion(PtrExpr);16490 if (PtrConv.isInvalid())16491 return PtrConv;16492 PtrExpr = PtrConv.get();16493 TheCall->setArg(1, PtrExpr);16494 if (PtrExpr->isTypeDependent()) {16495 TheCall->setType(Context.DependentTy);16496 return TheCall;16497 }16498 }16499 16500 // Check pointer argument.16501 auto *PtrTy = PtrExpr->getType()->getAs<PointerType>();16502 if (!PtrTy) {16503 Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type)16504 << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 5 << 016505 << PtrExpr->getType();16506 ArgError = true;16507 } else {16508 QualType ElementTy = PtrTy->getPointeeType();16509 if (ElementTy.isConstQualified()) {16510 Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_store_to_const);16511 ArgError = true;16512 }16513 ElementTy = ElementTy.getUnqualifiedType().getCanonicalType();16514 if (MatrixTy &&16515 !Context.hasSameType(ElementTy, MatrixTy->getElementType())) {16516 Diag(PtrExpr->getBeginLoc(),16517 diag::err_builtin_matrix_pointer_arg_mismatch)16518 << ElementTy << MatrixTy->getElementType();16519 ArgError = true;16520 }16521 }16522 16523 // Apply default Lvalue conversions and convert the stride expression to16524 // size_t.16525 {16526 ExprResult StrideConv = DefaultLvalueConversion(StrideExpr);16527 if (StrideConv.isInvalid())16528 return StrideConv;16529 16530 StrideConv = tryConvertExprToType(StrideConv.get(), Context.getSizeType());16531 if (StrideConv.isInvalid())16532 return StrideConv;16533 StrideExpr = StrideConv.get();16534 TheCall->setArg(2, StrideExpr);16535 }16536 16537 // Check stride argument.16538 if (MatrixTy) {16539 if (std::optional<llvm::APSInt> Value =16540 StrideExpr->getIntegerConstantExpr(Context)) {16541 uint64_t Stride = Value->getZExtValue();16542 if (Stride < MatrixTy->getNumRows()) {16543 Diag(StrideExpr->getBeginLoc(),16544 diag::err_builtin_matrix_stride_too_small);16545 ArgError = true;16546 }16547 }16548 }16549 16550 if (ArgError)16551 return ExprError();16552 16553 return CallResult;16554}16555 16556void Sema::CheckTCBEnforcement(const SourceLocation CallExprLoc,16557 const NamedDecl *Callee) {16558 // This warning does not make sense in code that has no runtime behavior.16559 if (isUnevaluatedContext())16560 return;16561 16562 const NamedDecl *Caller = getCurFunctionOrMethodDecl();16563 16564 if (!Caller || !Caller->hasAttr<EnforceTCBAttr>())16565 return;16566 16567 // Search through the enforce_tcb and enforce_tcb_leaf attributes to find16568 // all TCBs the callee is a part of.16569 llvm::StringSet<> CalleeTCBs;16570 for (const auto *A : Callee->specific_attrs<EnforceTCBAttr>())16571 CalleeTCBs.insert(A->getTCBName());16572 for (const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())16573 CalleeTCBs.insert(A->getTCBName());16574 16575 // Go through the TCBs the caller is a part of and emit warnings if Caller16576 // is in a TCB that the Callee is not.16577 for (const auto *A : Caller->specific_attrs<EnforceTCBAttr>()) {16578 StringRef CallerTCB = A->getTCBName();16579 if (CalleeTCBs.count(CallerTCB) == 0) {16580 this->Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)16581 << Callee << CallerTCB;16582 }16583 }16584}16585