aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
index 746eb82a5bdc..f25694ce48c9 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
@@ -341,7 +341,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {
return DiagnoseUnusedExprResult(POE->getSemanticExpr(0), DiagID);
if (isa<ObjCSubscriptRefExpr>(Source))
DiagID = diag::warn_unused_container_subscript_expr;
- else
+ else if (isa<ObjCPropertyRefExpr>(Source))
DiagID = diag::warn_unused_property_expr;
} else if (const CXXFunctionalCastExpr *FC
= dyn_cast<CXXFunctionalCastExpr>(E)) {
@@ -442,7 +442,16 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
}
- return CompoundStmt::Create(Context, Elts, L, R);
+ // Calculate difference between FP options in this compound statement and in
+ // the enclosing one. If this is a function body, take the difference against
+ // default options. In this case the difference will indicate options that are
+ // changed upon entry to the statement.
+ FPOptions FPO = (getCurFunction()->CompoundScopes.size() == 1)
+ ? FPOptions(getLangOpts())
+ : getCurCompoundScope().InitialFPFeatures;
+ FPOptionsOverride FPDiff = getCurFPFeatures().getChangesFrom(FPO);
+
+ return CompoundStmt::Create(Context, Elts, FPDiff, L, R);
}
ExprResult
@@ -587,7 +596,7 @@ StmtResult Sema::BuildAttributedStmt(SourceLocation AttrsLoc,
return AttributedStmt::Create(Context, AttrsLoc, Attrs, SubStmt);
}
-StmtResult Sema::ActOnAttributedStmt(const ParsedAttributesWithRange &Attrs,
+StmtResult Sema::ActOnAttributedStmt(const ParsedAttributes &Attrs,
Stmt *SubStmt) {
SmallVector<const Attr *, 1> SemanticAttrs;
ProcessStmtAttributes(SubStmt, Attrs, SemanticAttrs);
@@ -888,8 +897,7 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc,
CommaVisitor(*this).Visit(CondExpr);
if (!ConstevalOrNegatedConsteval && !elseStmt)
- DiagnoseEmptyStmtBody(CondExpr->getEndLoc(), thenStmt,
- diag::warn_empty_if_body);
+ DiagnoseEmptyStmtBody(RParenLoc, thenStmt, diag::warn_empty_if_body);
if (ConstevalOrNegatedConsteval ||
StatementKind == IfStatementKind::Constexpr) {
@@ -3312,7 +3320,7 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
// C99 6.8.6.2p1: A break shall appear only in or as a loop body.
return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
}
- if (S->getFlags() & Scope::ConditionVarScope) {
+ if (S->isConditionVarScope()) {
// We cannot 'continue;' from within a statement expression in the
// initializer of a condition variable because we would jump past the
// initialization of that variable.
@@ -3762,8 +3770,8 @@ TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const {
bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
SourceLocation ReturnLoc,
Expr *&RetExpr,
- AutoType *AT) {
- // If this is the conversion function for a lambda, we choose to deduce it
+ const AutoType *AT) {
+ // If this is the conversion function for a lambda, we choose to deduce its
// type from the corresponding call operator, not from the synthesized return
// statement within it. See Sema::DeduceReturnType.
if (isLambdaConversionOperator(FD))
@@ -3808,19 +3816,26 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
LocalTypedefNameReferencer Referencer(*this);
Referencer.TraverseType(RetExpr->getType());
} else {
- // In the case of a return with no operand, the initializer is considered
- // to be void().
- //
- // Deduction here can only succeed if the return type is exactly 'cv auto'
- // or 'decltype(auto)', so just check for that case directly.
+ // For a function with a deduced result type to return void,
+ // the result type as written must be 'auto' or 'decltype(auto)',
+ // possibly cv-qualified or constrained, but not ref-qualified.
if (!OrigResultType.getType()->getAs<AutoType>()) {
Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
<< OrigResultType.getType();
return true;
}
- // We always deduce U = void in this case.
- Deduced = SubstAutoType(OrigResultType.getType(), Context.VoidTy);
- if (Deduced.isNull())
+ // In the case of a return with no operand, the initializer is considered
+ // to be 'void()'.
+ Expr *Dummy = new (Context) CXXScalarValueInitExpr(
+ Context.VoidTy,
+ Context.getTrivialTypeSourceInfo(Context.VoidTy, ReturnLoc), ReturnLoc);
+ DeduceAutoResult DAR = DeduceAutoType(OrigResultType, Dummy, Deduced);
+
+ if (DAR == DAR_Failed && !FD->isInvalidDecl())
+ Diag(ReturnLoc, diag::err_auto_fn_deduction_failure)
+ << OrigResultType.getType() << Dummy->getType();
+
+ if (DAR != DAR_Succeeded)
return true;
}
@@ -4098,7 +4113,9 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
} else if (!RetValExp && !HasDependentReturnType) {
FunctionDecl *FD = getCurFunctionDecl();
- if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) {
+ if ((FD && FD->isInvalidDecl()) || FnRetType->containsErrors()) {
+ // The intended return type might have been "void", so don't warn.
+ } else if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) {
// C++11 [stmt.return]p2
Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)
<< FD << FD->isConsteval();