aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-02-15 20:49:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-02-15 20:49:05 +0000
commit5df36aae6442dbc915e71d1f0339b615af064b1b (patch)
tree61d7c7f2e6672b6a34584efb7757f9fa14742759 /lib
parentd87c9e7da2e87f224c426832f08897269c2e5636 (diff)
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/Basic/Targets/PPC.h8
-rw-r--r--lib/CodeGen/CGBuiltin.cpp5
-rw-r--r--lib/CodeGen/CGDecl.cpp10
-rw-r--r--lib/CodeGen/CodeGenModule.cpp8
-rw-r--r--lib/CodeGen/TargetInfo.cpp16
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp8
-rw-r--r--lib/Frontend/InitPreprocessor.cpp7
-rw-r--r--lib/Headers/intrin.h4
-rw-r--r--lib/Parse/ParseObjc.cpp2
-rw-r--r--lib/Parse/ParseOpenMP.cpp14
-rw-r--r--lib/Parse/ParsePragma.cpp9
-rw-r--r--lib/Parse/ParseStmt.cpp26
-rw-r--r--lib/Parse/ParseStmtAsm.cpp2
-rw-r--r--lib/Sema/Sema.cpp7
-rw-r--r--lib/Sema/SemaChecking.cpp20
-rw-r--r--lib/Sema/SemaCoroutine.cpp17
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaDeclAttr.cpp77
-rw-r--r--lib/Sema/SemaDeclCXX.cpp14
-rw-r--r--lib/Sema/SemaExpr.cpp5
-rw-r--r--lib/Sema/SemaExprCXX.cpp2
-rw-r--r--lib/Sema/SemaLambda.cpp2
-rw-r--r--lib/Sema/SemaOpenMP.cpp55
-rw-r--r--lib/Sema/SemaStmt.cpp65
-rw-r--r--lib/Sema/TreeTransform.h15
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp29
26 files changed, 264 insertions, 169 deletions
diff --git a/lib/Basic/Targets/PPC.h b/lib/Basic/Targets/PPC.h
index 058970a0e098..cbe7a9a2fa85 100644
--- a/lib/Basic/Targets/PPC.h
+++ b/lib/Basic/Targets/PPC.h
@@ -331,9 +331,15 @@ public:
break;
}
- if (getTriple().isOSFreeBSD()) {
+ switch (getTriple().getOS()) {
+ case llvm::Triple::FreeBSD:
+ case llvm::Triple::NetBSD:
+ case llvm::Triple::OpenBSD:
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+ break;
+ default:
+ break;
}
// PPC32 supports atomics up to 4 bytes.
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index a718f2f19aa6..ccc657493b28 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -7052,19 +7052,16 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
llvm::Type *RegisterType = Int64Ty;
- llvm::Type *ValueType = Int32Ty;
llvm::Type *Types[] = { RegisterType };
if (BuiltinID == AArch64::BI_ReadStatusReg) {
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
- llvm::Value *Call = Builder.CreateCall(F, Metadata);
- return Builder.CreateTrunc(Call, ValueType);
+ return Builder.CreateCall(F, Metadata);
}
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
llvm::Value *ArgValue = EmitScalarExpr(E->getArg(1));
- ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
return Builder.CreateCall(F, { Metadata, ArgValue });
}
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 5959d889b455..b98657ffd800 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -1631,11 +1631,15 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
? LangOptions::TrivialAutoVarInitKind::Uninitialized
: getContext().getLangOpts().getTrivialAutoVarInit()));
- auto initializeWhatIsTechnicallyUninitialized = [&]() {
+ auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
if (trivialAutoVarInit ==
LangOptions::TrivialAutoVarInitKind::Uninitialized)
return;
+ // Only initialize a __block's storage: we always initialize the header.
+ if (emission.IsEscapingByRef)
+ Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
+
CharUnits Size = getContext().getTypeSizeInChars(type);
if (!Size.isZero()) {
switch (trivialAutoVarInit) {
@@ -1713,7 +1717,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
};
if (isTrivialInitializer(Init)) {
- initializeWhatIsTechnicallyUninitialized();
+ initializeWhatIsTechnicallyUninitialized(Loc);
return;
}
@@ -1727,7 +1731,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
}
if (!constant) {
- initializeWhatIsTechnicallyUninitialized();
+ initializeWhatIsTechnicallyUninitialized(Loc);
LValue lv = MakeAddrLValue(Loc, type);
lv.setNonGC(true);
return EmitExprAsInit(Init, &D, lv, capturedByInit);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 244738042cef..2ac59fb4de25 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -3762,13 +3762,15 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
}
}
- // Microsoft's link.exe doesn't support alignments greater than 32 for common
- // symbols, so symbols with greater alignment requirements cannot be common.
+ // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
+ // common symbols, so symbols with greater alignment requirements cannot be
+ // common.
// Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
// alignments for common symbols via the aligncomm directive, so this
// restriction only applies to MSVC environments.
if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
- Context.getTypeAlignIfKnown(D->getType()) > 32)
+ Context.getTypeAlignIfKnown(D->getType()) >
+ Context.toBits(CharUnits::fromQuantity(32)))
return true;
return false;
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index f5a770ed9d84..94fccb15ff6e 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -761,6 +761,22 @@ public:
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const override {
+ TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
+ if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ if (const auto *Attr = FD->getAttr<WebAssemblyImportModuleAttr>()) {
+ llvm::Function *Fn = cast<llvm::Function>(GV);
+ llvm::AttrBuilder B;
+ B.addAttribute("wasm-import-module", Attr->getImportModule());
+ Fn->addAttributes(llvm::AttributeList::FunctionIndex, B);
+ }
+ if (const auto *Attr = FD->getAttr<WebAssemblyImportNameAttr>()) {
+ llvm::Function *Fn = cast<llvm::Function>(GV);
+ llvm::AttrBuilder B;
+ B.addAttribute("wasm-import-name", Attr->getImportName());
+ Fn->addAttributes(llvm::AttributeList::FunctionIndex, B);
+ }
+ }
+
if (auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
llvm::Function *Fn = cast<llvm::Function>(GV);
if (!FD->doesThisDeclarationHaveABody() && !FD->hasPrototype())
diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp
index 7e34b0df5c8c..a164fd68e22e 100644
--- a/lib/Driver/ToolChains/MSVC.cpp
+++ b/lib/Driver/ToolChains/MSVC.cpp
@@ -1408,10 +1408,10 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
DAL.AddFlagArg(
A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
} else {
- // Don't warn about /Oy- in 64-bit builds (where
+ // Don't warn about /Oy- in x86-64 builds (where
// SupportsForcingFramePointer is false). The flag having no effect
// there is a compiler-internal optimization, and people shouldn't have
- // to special-case their build files for 64-bit clang-cl.
+ // to special-case their build files for x86-64 clang-cl.
A->claim();
}
break;
@@ -1442,8 +1442,8 @@ MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
const OptTable &Opts = getDriver().getOpts();
- // /Oy and /Oy- only has an effect under X86-32.
- bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
+ // /Oy and /Oy- don't have an effect on X86-64
+ bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
// The -O[12xd] flag actually expands to several flags. We must desugar the
// flags so that options embedded can be negated. For example, the '-O2' flag
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 66807b097d40..4cde22ce9aa4 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -1059,10 +1059,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// OpenCL definitions.
if (LangOpts.OpenCL) {
-#define OPENCLEXT(Ext) \
- if (TI.getSupportedOpenCLOpts().isSupported(#Ext, \
- LangOpts.OpenCLVersion)) \
- Builder.defineMacro(#Ext);
+#define OPENCLEXT(Ext) \
+ if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \
+ Builder.defineMacro(#Ext);
#include "clang/Basic/OpenCLExtensions.def"
auto Arch = TI.getTriple().getArch();
diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h
index c86f41faeb88..966258bab4b3 100644
--- a/lib/Headers/intrin.h
+++ b/lib/Headers/intrin.h
@@ -564,8 +564,8 @@ __nop(void) {
#if defined(__aarch64__)
unsigned __int64 __getReg(int);
long _InterlockedAdd(long volatile *Addend, long Value);
-int _ReadStatusReg(int);
-void _WriteStatusReg(int, int);
+__int64 _ReadStatusReg(int);
+void _WriteStatusReg(int, __int64);
static inline unsigned short _byteswap_ushort (unsigned short val) {
return __builtin_bswap16(val);
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index bd55f7179399..c8d7bda3d6e9 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -2741,7 +2741,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
// Otherwise, eat the semicolon.
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Res, isExprValueDiscarded());
+ return Actions.ActOnExprStmt(Res);
}
ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index dd2a8aae9f2f..17c3fa3cf2aa 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
ExprResult CombinerResult =
Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
- D->getLocation(), /*DiscardedValue*/ false);
+ D->getLocation(), /*DiscardedValue=*/true);
Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
@@ -356,7 +356,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
if (Actions.getLangOpts().CPlusPlus) {
InitializerResult = Actions.ActOnFinishFullExpr(
ParseAssignmentExpression().get(), D->getLocation(),
- /*DiscardedValue*/ false);
+ /*DiscardedValue=*/true);
} else {
ConsumeToken();
ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
@@ -364,7 +364,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
} else {
InitializerResult = Actions.ActOnFinishFullExpr(
ParseAssignmentExpression().get(), D->getLocation(),
- /*DiscardedValue*/ false);
+ /*DiscardedValue=*/true);
}
Actions.ActOnOpenMPDeclareReductionInitializerEnd(
D, InitializerResult.get(), OmpPrivParm);
@@ -1455,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
ExprResult LHS(ParseCastExpression(
/*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
- Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
+ Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
// Parse ')'.
RLoc = Tok.getLocation();
@@ -1711,8 +1711,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
SourceLocation ELoc = Tok.getLocation();
ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
- Val =
- Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
+ Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
}
// Parse ')'.
@@ -1997,8 +1996,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
Data.ColonLoc = Tok.getLocation();
SourceLocation ELoc = ConsumeToken();
ExprResult Tail = ParseAssignmentExpression();
- Tail =
- Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
+ Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
if (Tail.isUsable())
Data.TailExpr = Tail.get();
else
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 380eb64997a7..7e9b1011e81a 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -693,13 +693,12 @@ void Parser::HandlePragmaOpenCLExtension() {
if (Name == "all") {
if (State == Disable) {
Opt.disableAll();
- Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
+ Opt.enableSupportedCore(getLangOpts());
} else {
PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
}
} else if (State == Begin) {
- if (!Opt.isKnown(Name) ||
- !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
+ if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
Opt.support(Name);
}
Actions.setCurrentOpenCLExtension(Name);
@@ -709,9 +708,9 @@ void Parser::HandlePragmaOpenCLExtension() {
Actions.setCurrentOpenCLExtension("");
} else if (!Opt.isKnown(Name))
PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
- else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
+ else if (Opt.isSupportedExtension(Name, getLangOpts()))
Opt.enable(Name, State == Enable);
- else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
+ else if (Opt.isSupportedCore(Name, getLangOpts()))
PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
else
PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 2974e6a245b0..313793c3e8fb 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -439,7 +439,7 @@ StmtResult Parser::ParseExprStatement() {
// Otherwise, eat the semicolon.
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Expr, isExprValueDiscarded());
+ return Actions.ActOnExprStmt(Expr);
}
/// ParseSEHTryBlockCommon
@@ -958,16 +958,6 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
return true;
}
-bool Parser::isExprValueDiscarded() {
- if (Actions.isCurCompoundStmtAStmtExpr()) {
- // Look to see if the next two tokens close the statement expression;
- // if so, this expression statement is the last statement in a
- // statment expression.
- return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren);
- }
- return true;
-}
-
/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
/// ActOnCompoundStmt action. This expects the '{' to be the current token, and
/// consume the '}' at the end of the block. It does not manipulate the scope
@@ -1072,7 +1062,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
// Eat the semicolon at the end of stmt and convert the expr into a
// statement.
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
- R = Actions.ActOnExprStmt(Res, isExprValueDiscarded());
+ R = Actions.ActOnExprStmt(Res);
}
}
@@ -1708,16 +1698,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
if (!Value.isInvalid()) {
if (ForEach)
FirstPart = Actions.ActOnForEachLValueExpr(Value.get());
- else {
- // We already know this is not an init-statement within a for loop, so
- // if we are parsing a C++11 range-based for loop, we should treat this
- // expression statement as being a discarded value expression because
- // we will err below. This way we do not warn on an unused expression
- // that was an error in the first place, like with: for (expr : expr);
- bool IsRangeBasedFor =
- getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
- FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);
- }
+ else
+ FirstPart = Actions.ActOnExprStmt(Value);
}
if (Tok.is(tok::semi)) {
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
index 9b96c5150e56..3f5af7d44f36 100644
--- a/lib/Parse/ParseStmtAsm.cpp
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -637,7 +637,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
// Filter out "fpsw" and "mxcsr". They aren't valid GCC asm clobber
// constraints. Clang always adds fpsr to the clobber list anyway.
llvm::erase_if(Clobbers, [](const std::string &C) {
- return C == "fpsw" || C == "mxcsr";
+ return C == "fpsr" || C == "mxcsr";
});
// Build the vector of clobber StringRefs.
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 9fa39968625a..9d33ec519092 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -256,11 +256,12 @@ void Sema::Initialize() {
// Initialize predefined OpenCL types and supported extensions and (optional)
// core features.
if (getLangOpts().OpenCL) {
- getOpenCLOptions().addSupport(Context.getTargetInfo().getSupportedOpenCLOpts());
- getOpenCLOptions().enableSupportedCore(getLangOpts().OpenCLVersion);
+ getOpenCLOptions().addSupport(
+ Context.getTargetInfo().getSupportedOpenCLOpts());
+ getOpenCLOptions().enableSupportedCore(getLangOpts());
addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
addImplicitTypedef("event_t", Context.OCLEventTy);
- if (getLangOpts().OpenCLVersion >= 200) {
+ if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) {
addImplicitTypedef("clk_event_t", Context.OCLClkEventTy);
addImplicitTypedef("queue_t", Context.OCLQueueTy);
addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy);
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 8dc1fdb76988..b2c727b5c483 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -10622,16 +10622,16 @@ static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
// The below checks assume source is floating point.
if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return;
- // If source is floating point but target is not.
- if (!ResultBT->isFloatingPoint())
- return DiagnoseFloatingImpCast(S, E, E->getRHS()->getType(),
- E->getExprLoc());
-
- // If both source and target are floating points.
- // Builtin FP kinds are ordered by increasing FP rank.
- if (ResultBT->getKind() < RBT->getKind() &&
- // We don't want to warn for system macro.
- !S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
+ // If source is floating point but target is an integer.
+ if (ResultBT->isInteger())
+ DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(),
+ E->getExprLoc(), diag::warn_impcast_float_integer);
+ // If both source and target are floating points. Builtin FP kinds are ordered
+ // by increasing FP rank. FIXME: except _Float16, we currently emit a bogus
+ // warning.
+ else if (ResultBT->isFloatingPoint() && ResultBT->getKind() < RBT->getKind() &&
+ // We don't want to warn for system macro.
+ !S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
// warn about dropping FP rank.
DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(),
diag::warn_impcast_float_result_precision);
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 181efa6d3dd0..e282bb62f032 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -646,7 +646,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
return StmtError();
Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(),
/*IsImplicit*/ true);
- Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
+ Suspend = ActOnFinishFullExpr(Suspend.get());
if (Suspend.isInvalid()) {
Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
<< ((Name == "initial_suspend") ? 0 : 1);
@@ -867,7 +867,7 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
if (PC.isInvalid())
return StmtError();
- Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
+ Expr *PCE = ActOnFinishFullExpr(PC.get()).get();
Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
return Res;
@@ -1236,7 +1236,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
ExprResult NewExpr =
S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
- NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false);
+ NewExpr = S.ActOnFinishFullExpr(NewExpr.get());
if (NewExpr.isInvalid())
return false;
@@ -1262,8 +1262,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
ExprResult DeleteExpr =
S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
- DeleteExpr =
- S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false);
+ DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get());
if (DeleteExpr.isInvalid())
return false;
@@ -1348,8 +1347,7 @@ bool CoroutineStmtBuilder::makeOnException() {
ExprResult UnhandledException = buildPromiseCall(S, Fn.CoroutinePromise, Loc,
"unhandled_exception", None);
- UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc,
- /*DiscardedValue*/ false);
+ UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc);
if (UnhandledException.isInvalid())
return false;
@@ -1402,8 +1400,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
"get_return_object type must no longer be dependent");
if (FnRetType->isVoidType()) {
- ExprResult Res =
- S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false);
+ ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc);
if (Res.isInvalid())
return false;
@@ -1435,7 +1432,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
if (Res.isInvalid())
return false;
- Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false);
+ Res = S.ActOnFinishFullExpr(Res.get());
if (Res.isInvalid())
return false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 23c99d45a78d..7ddf2e88b787 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11200,9 +11200,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// struct T { S a, b; } t = { Temp(), Temp() }
//
// we should destroy the first Temp before constructing the second.
- ExprResult Result =
- ActOnFinishFullExpr(Init, VDecl->getLocation(),
- /*DiscardedValue*/ false, VDecl->isConstexpr());
+ ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(),
+ false,
+ VDecl->isConstexpr());
if (Result.isInvalid()) {
VDecl->setInvalidDecl();
return;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 139ac8aab433..c4c3598ee7f3 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5116,11 +5116,22 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D,
static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
const ParsedAttr &AL) {
+ DeclContext *Ctx = D->getDeclContext();
+
+ // This attribute can only be applied to methods in interfaces or class
+ // extensions.
+ if (!isa<ObjCInterfaceDecl>(Ctx) &&
+ !(isa<ObjCCategoryDecl>(Ctx) &&
+ cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
+ S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
+ return;
+ }
+
ObjCInterfaceDecl *IFace;
- if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
+ if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
IFace = CatDecl->getClassInterface();
else
- IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
+ IFace = cast<ObjCInterfaceDecl>(Ctx);
if (!IFace)
return;
@@ -5577,6 +5588,51 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
}
+static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!isFunctionOrMethod(D)) {
+ S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+ << "'import_module'" << ExpectedFunction;
+ return;
+ }
+
+ auto *FD = cast<FunctionDecl>(D);
+ if (FD->isThisDeclarationADefinition()) {
+ S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+ return;
+ }
+
+ StringRef Str;
+ SourceLocation ArgLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
+ return;
+
+ FD->addAttr(::new (S.Context) WebAssemblyImportModuleAttr(
+ AL.getRange(), S.Context, Str,
+ AL.getAttributeSpellingListIndex()));
+}
+
+static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!isFunctionOrMethod(D)) {
+ S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+ << "'import_name'" << ExpectedFunction;
+ return;
+ }
+
+ auto *FD = cast<FunctionDecl>(D);
+ if (FD->isThisDeclarationADefinition()) {
+ S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+ return;
+ }
+
+ StringRef Str;
+ SourceLocation ArgLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
+ return;
+
+ FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(
+ AL.getRange(), S.Context, Str,
+ AL.getAttributeSpellingListIndex()));
+}
static void handleRISCVInterruptAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
@@ -6330,6 +6386,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AVRSignal:
handleAVRSignalAttr(S, D, AL);
break;
+ case ParsedAttr::AT_WebAssemblyImportModule:
+ handleWebAssemblyImportModuleAttr(S, D, AL);
+ break;
+ case ParsedAttr::AT_WebAssemblyImportName:
+ handleWebAssemblyImportNameAttr(S, D, AL);
+ break;
case ParsedAttr::AT_IBAction:
handleSimpleAttribute<IBActionAttr>(S, D, AL);
break;
@@ -7016,6 +7078,17 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
}
}
}
+
+ // Do this check after processing D's attributes because the attribute
+ // objc_method_family can change whether the given method is in the init
+ // family, and it can be applied after objc_designated_initializer. This is a
+ // bit of a hack, but we need it to be compatible with versions of clang that
+ // processed the attribute list in the wrong order.
+ if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
+ cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
+ Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
+ D->dropAttr<ObjCDesignatedInitializerAttr>();
+ }
}
// Helper for delayed processing TransparentUnion attribute.
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8b3556f715bf..950a63aa451b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1205,7 +1205,7 @@ static bool checkTupleLikeDecomposition(Sema &S,
E = Seq.Perform(S, Entity, Kind, Init);
if (E.isInvalid())
return true;
- E = S.ActOnFinishFullExpr(E.get(), Loc, /*DiscardedValue*/ false);
+ E = S.ActOnFinishFullExpr(E.get(), Loc);
if (E.isInvalid())
return true;
RefVD->setInit(E.get());
@@ -3686,7 +3686,7 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
// C++11 [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ false);
+ Init = ActOnFinishFullExpr(Init.get(), InitLoc);
if (Init.isInvalid()) {
FD->setInvalidDecl();
return;
@@ -4044,8 +4044,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
// C++11 [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin(),
- /*DiscardedValue*/ false);
+ MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin());
if (MemberInit.isInvalid())
return true;
@@ -4100,8 +4099,8 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
// C++11 [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- DelegationInit = ActOnFinishFullExpr(
- DelegationInit.get(), InitRange.getBegin(), /*DiscardedValue*/ false);
+ DelegationInit = ActOnFinishFullExpr(DelegationInit.get(),
+ InitRange.getBegin());
if (DelegationInit.isInvalid())
return true;
@@ -4230,8 +4229,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
// C++11 [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(),
- /*DiscardedValue*/ false);
+ BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin());
if (BaseInit.isInvalid())
return true;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2bcd47abe356..db0c62630a9e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4723,9 +4723,8 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
if (Result.isInvalid())
return true;
- Result =
- ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
- /*DiscardedValue*/ false);
+ Result = ActOnFinishFullExpr(Result.getAs<Expr>(),
+ Param->getOuterLocStart());
if (Result.isInvalid())
return true;
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8c89a3cee3db..cce7a216548f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -7815,8 +7815,6 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
FullExpr = IgnoredValueConversions(FullExpr.get());
if (FullExpr.isInvalid())
return ExprError();
-
- DiagnoseUnusedExprResult(FullExpr.get());
}
FullExpr = CorrectDelayedTyposInExpr(FullExpr.get());
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index af233b96d69b..4e002a853dc2 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -1724,7 +1724,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
/*NRVO=*/false),
CurrentLocation, Src);
if (!Init.isInvalid())
- Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
+ Init = ActOnFinishFullExpr(Init.get());
if (Init.isInvalid())
return ExprError();
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 36048a38b999..aedec746af9e 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -5367,7 +5367,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
LastIteration.get(), UB.get());
EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
CondOp.get());
- EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
+ EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
// If we have a combined directive that combines 'distribute', 'for' or
// 'simd' we need to be able to access the bounds of the schedule of the
@@ -5396,8 +5396,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
LastIteration.get(), CombUB.get());
CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
CombCondOp.get());
- CombEUB =
- SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
+ CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
// We expect to have at least 2 more parameters than the 'parallel'
@@ -5431,7 +5430,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
? LB.get()
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
- Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
+ Init = SemaRef.ActOnFinishFullExpr(Init.get());
if (isOpenMPLoopBoundSharingDirective(DKind)) {
Expr *CombRHS =
@@ -5442,8 +5441,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
CombInit =
SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
- CombInit =
- SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
+ CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
}
}
@@ -5475,7 +5473,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
if (!Inc.isUsable())
return 0;
Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
- Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
+ Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
if (!Inc.isUsable())
return 0;
@@ -5493,8 +5491,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// LB = LB + ST
NextLB =
SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
- NextLB =
- SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
+ NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
if (!NextLB.isUsable())
return 0;
// UB + ST
@@ -5504,8 +5501,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// UB = UB + ST
NextUB =
SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
- NextUB =
- SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
+ NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
if (!NextUB.isUsable())
return 0;
if (isOpenMPLoopBoundSharingDirective(DKind)) {
@@ -5516,8 +5512,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// LB = LB + ST
CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
CombNextLB.get());
- CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
- /*DiscardedValue*/ false);
+ CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
if (!CombNextLB.isUsable())
return 0;
// UB + ST
@@ -5528,8 +5523,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// UB = UB + ST
CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
CombNextUB.get());
- CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
- /*DiscardedValue*/ false);
+ CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
if (!CombNextUB.isUsable())
return 0;
}
@@ -5550,8 +5544,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
assert(DistInc.isUsable() && "distribute inc expr was not built");
DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
DistInc.get());
- DistInc =
- SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
+ DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
assert(DistInc.isUsable() && "distribute inc expr was not built");
// Build expression: UB = min(UB, prevUB) for #for in composite or combined
@@ -5563,8 +5556,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
CondOp.get());
- PrevEUB =
- SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
+ PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
// Build IV <= PrevUB to be used in parallel for is in combination with
// a distribute directive with schedule(static, 1)
@@ -5680,10 +5672,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Built.IterationVarRef = IV.get();
Built.LastIteration = LastIteration.get();
Built.NumIterations = NumIterations.get();
- Built.CalcLastIteration = SemaRef
- .ActOnFinishFullExpr(CalcLastIteration.get(),
- /*DiscardedValue*/ false)
- .get();
+ Built.CalcLastIteration =
+ SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
Built.PreCond = PreCond.get();
Built.PreInits = buildPreInits(C, Captures);
Built.Cond = Cond.get();
@@ -10358,8 +10348,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
PseudoDstExpr, PseudoSrcExpr);
if (AssignmentOp.isInvalid())
continue;
- AssignmentOp =
- ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
+ AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
+ /*DiscardedValue=*/true);
if (AssignmentOp.isInvalid())
continue;
@@ -11357,8 +11347,7 @@ static bool actOnOMPReductionKindClause(
BO_Assign, LHSDRE, ConditionalOp);
}
if (ReductionOp.isUsable())
- ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
- /*DiscardedValue*/ false);
+ ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
}
if (!ReductionOp.isUsable())
continue;
@@ -11688,7 +11677,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
ExprResult CalcStep =
BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
- CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
+ CalcStep = ActOnFinishFullExpr(CalcStep.get());
// Warn about zero linear step (it would be probably better specified as
// making corresponding variables 'const').
@@ -11776,7 +11765,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
else
Update = *CurPrivate;
Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
- /*DiscardedValue*/ false);
+ /*DiscardedValue=*/true);
// Build final: Var = InitExpr + NumIterations * Step
ExprResult Final;
@@ -11787,7 +11776,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
else
Final = *CurPrivate;
Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
- /*DiscardedValue*/ false);
+ /*DiscardedValue=*/true);
if (!Update.isUsable() || !Final.isUsable()) {
Updates.push_back(nullptr);
@@ -11955,7 +11944,7 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
if (AssignmentOp.isInvalid())
continue;
AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
- /*DiscardedValue*/ false);
+ /*DiscardedValue=*/true);
if (AssignmentOp.isInvalid())
continue;
@@ -12063,8 +12052,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
if (AssignmentOp.isInvalid())
continue;
- AssignmentOp =
- ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
+ AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
+ /*DiscardedValue=*/true);
if (AssignmentOp.isInvalid())
continue;
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9e30c9a396c0..dacf8d0cf4e7 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -42,11 +42,12 @@
using namespace clang;
using namespace sema;
-StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) {
+StmtResult Sema::ActOnExprStmt(ExprResult FE) {
if (FE.isInvalid())
return StmtError();
- FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue);
+ FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(),
+ /*DiscardedValue*/ true);
if (FE.isInvalid())
return StmtError();
@@ -347,10 +348,6 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
return getCurFunction()->CompoundScopes.back();
}
-bool Sema::isCurCompoundStmtAStmtExpr() const {
- return getCurCompoundScope().IsStmtExpr;
-}
-
StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
ArrayRef<Stmt *> Elts, bool isStmtExpr) {
const unsigned NumElts = Elts.size();
@@ -373,6 +370,14 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
Diag(D->getLocation(), diag::ext_mixed_decls_code);
}
}
+ // Warn about unused expressions in statements.
+ for (unsigned i = 0; i != NumElts; ++i) {
+ // Ignore statements that are last in a statement expression.
+ if (isStmtExpr && i == NumElts - 1)
+ continue;
+
+ DiagnoseUnusedExprResult(Elts[i]);
+ }
// Check for suspicious empty body (null statement) in `for' and `while'
// statements. Don't do anything for template instantiations, this just adds
@@ -464,12 +469,15 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,
/// ActOnCaseStmtBody - This installs a statement as the body of a case.
void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {
+ DiagnoseUnusedExprResult(SubStmt);
cast<CaseStmt>(S)->setSubStmt(SubStmt);
}
StmtResult
Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
Stmt *SubStmt, Scope *CurScope) {
+ DiagnoseUnusedExprResult(SubStmt);
+
if (getCurFunction()->SwitchStack.empty()) {
Diag(DefaultLoc, diag::err_default_not_in_switch);
return SubStmt;
@@ -563,6 +571,9 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr,
if (IsConstexpr || isa<ObjCAvailabilityCheckExpr>(Cond.get().second))
setFunctionHasBranchProtectedScope();
+ DiagnoseUnusedExprResult(thenStmt);
+ DiagnoseUnusedExprResult(elseStmt);
+
return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first,
Cond.get().second, thenStmt, ElseLoc, elseStmt);
}
@@ -1290,6 +1301,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
!Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
CommaVisitor(*this).Visit(CondVal.second);
+ DiagnoseUnusedExprResult(Body);
+
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
@@ -1309,7 +1322,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
return StmtError();
Cond = CondResult.get();
- CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false);
+ CondResult = ActOnFinishFullExpr(Cond, DoLoc);
if (CondResult.isInvalid())
return StmtError();
Cond = CondResult.get();
@@ -1319,6 +1332,8 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
!Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc()))
CommaVisitor(*this).Visit(Cond);
+ DiagnoseUnusedExprResult(Body);
+
return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
}
@@ -1763,6 +1778,11 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
CommaVisitor(*this).Visit(Second.get().second);
Expr *Third = third.release().getAs<Expr>();
+
+ DiagnoseUnusedExprResult(First);
+ DiagnoseUnusedExprResult(Third);
+ DiagnoseUnusedExprResult(Body);
+
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
@@ -1782,7 +1802,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
if (result.isInvalid()) return StmtError();
E = result.get();
- ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
+ ExprResult FullExpr = ActOnFinishFullExpr(E);
if (FullExpr.isInvalid())
return StmtError();
return StmtResult(static_cast<Stmt*>(FullExpr.get()));
@@ -1936,8 +1956,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
if (CollectionExprResult.isInvalid())
return StmtError();
- CollectionExprResult =
- ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false);
+ CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
if (CollectionExprResult.isInvalid())
return StmtError();
@@ -2574,8 +2593,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
if (!NotEqExpr.isInvalid())
NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());
if (!NotEqExpr.isInvalid())
- NotEqExpr =
- ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false);
+ NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
if (NotEqExpr.isInvalid()) {
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
<< RangeLoc << 0 << BeginRangeRef.get()->getType();
@@ -2598,7 +2616,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
// co_await during the initial parse.
IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());
if (!IncrExpr.isInvalid())
- IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false);
+ IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
if (IncrExpr.isInvalid()) {
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
<< RangeLoc << 2 << BeginRangeRef.get()->getType() ;
@@ -2853,7 +2871,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
return StmtError();
}
- ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
+ ExprResult ExprRes = ActOnFinishFullExpr(E);
if (ExprRes.isInvalid())
return StmtError();
E = ExprRes.get();
@@ -3203,8 +3221,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
ExpressionEvaluationContext::DiscardedStatement &&
(HasDeducedReturnType || CurCap->HasImplicitReturnType)) {
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3331,8 +3348,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3562,8 +3578,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
ExpressionEvaluationContext::DiscardedStatement &&
FnRetType->getContainedAutoType()) {
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3657,8 +3672,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3737,8 +3751,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3791,7 +3804,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
if (Result.isInvalid())
return StmtError();
- Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false);
+ Result = ActOnFinishFullExpr(Result.get());
if (Result.isInvalid())
return StmtError();
Throw = Result.get();
@@ -3863,7 +3876,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {
}
// The operand to @synchronized is a full-expression.
- return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false);
+ return ActOnFinishFullExpr(operand);
}
StmtResult
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index df14768cbe81..9de4e8d654f9 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -328,7 +328,7 @@ public:
/// other mechanism.
///
/// \returns the transformed statement.
- StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false);
+ StmtResult TransformStmt(Stmt *S);
/// Transform the given statement.
///
@@ -3269,8 +3269,8 @@ private:
bool DeducibleTSTContext);
};
-template <typename Derived>
-StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
+template<typename Derived>
+StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
if (!S)
return S;
@@ -3294,7 +3294,7 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
if (E.isInvalid())
return StmtError();
- return getSema().ActOnExprStmt(E, DiscardedValue);
+ return getSema().ActOnExprStmt(E);
}
}
@@ -4715,8 +4715,7 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
}
if (SizeResult.isInvalid())
return QualType();
- SizeResult =
- SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
+ SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get());
if (SizeResult.isInvalid())
return QualType();
@@ -6521,9 +6520,7 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
bool SubStmtChanged = false;
SmallVector<Stmt*, 8> Statements;
for (auto *B : S->body()) {
- StmtResult Result =
- getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back());
-
+ StmtResult Result = getDerived().TransformStmt(B);
if (Result.isInvalid()) {
// Immediately fail if this was a DeclStmt, since it's very
// likely that this will cause problems for future statements.
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index da94b6eb21e9..ea695c4736a3 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -154,6 +154,32 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
return E;
}
+/// Comparing internal representations of symbolic values (via
+/// SVal::operator==()) is a valid way to check if the value was updated,
+/// unless it's a LazyCompoundVal that may have a different internal
+/// representation every time it is loaded from the state. In this function we
+/// do an approximate comparison for lazy compound values, checking that they
+/// are the immediate snapshots of the tracked region's bindings within the
+/// node's respective states but not really checking that these snapshots
+/// actually contain the same set of bindings.
+bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal,
+ const ExplodedNode *RightNode, SVal RightVal) {
+ if (LeftVal == RightVal)
+ return true;
+
+ const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>();
+ if (!LLCV)
+ return false;
+
+ const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>();
+ if (!RLCV)
+ return false;
+
+ return LLCV->getRegion() == RLCV->getRegion() &&
+ LLCV->getStore() == LeftNode->getState()->getStore() &&
+ RLCV->getStore() == RightNode->getState()->getStore();
+}
+
//===----------------------------------------------------------------------===//
// Definitions for bug reporter visitors.
//===----------------------------------------------------------------------===//
@@ -1188,7 +1214,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
if (Succ->getState()->getSVal(R) != V)
return nullptr;
- if (Pred->getState()->getSVal(R) == V) {
+ if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) {
Optional<PostStore> PS = Succ->getLocationAs<PostStore>();
if (!PS || PS->getLocationValue() != R)
return nullptr;
@@ -1209,6 +1235,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
// UndefinedVal.)
if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
if (const auto *VR = dyn_cast<VarRegion>(R)) {
+
const auto *Param = cast<ParmVarDecl>(VR->getDecl());
ProgramStateManager &StateMgr = BRC.getStateManager();