diff --git a/clang/include/clang/Testing/TestClangConfig.h b/clang/include/clang/Testing/TestClangConfig.h index e52aa37482dc1..b0687fe84655d 100644 --- a/clang/include/clang/Testing/TestClangConfig.h +++ b/clang/include/clang/Testing/TestClangConfig.h @@ -61,6 +61,8 @@ struct TestClangConfig { bool isC99OrLater() const { return isCOrLater(99); } + bool isC26OrLater() const { return isCOrLater(26); } + bool isCOrEarlier(int MaximumStdVersion) const { return isC() && (isC(MaximumStdVersion) || !isCOrLater(MaximumStdVersion)); } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index f21e571e6e0ce..134952689453a 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -550,11 +550,15 @@ struct CheckFallThroughDiagnostics { unsigned FunKind; // TODO: use diag::FalloffFunctionKind SourceLocation FuncLoc; - static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { + static CheckFallThroughDiagnostics MakeForFunction(const Sema &S, + const Decl *Func) { CheckFallThroughDiagnostics D; D.FuncLoc = Func->getLocation(); D.diag_FallThrough_HasNoReturn = diag::warn_noreturn_has_return_expr; D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid; + if (S.getLangOpts().C2y) { + D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid; + } // Don't suggest that virtual functions be marked "noreturn", since they // might be overridden by non-noreturn functions. @@ -598,11 +602,13 @@ struct CheckFallThroughDiagnostics { return D; } - bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid, + bool checkDiagnostics(const Sema &S, bool ReturnsVoid, bool HasNoReturn) const { + const DiagnosticsEngine &D = S.getDiagnostics(); if (FunKind == diag::FalloffFunctionKind::Function) { - return (ReturnsVoid || - D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) && + return ((ReturnsVoid || + D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) && + !S.getLangOpts().C2y) && (!HasNoReturn || D.isIgnored(diag::warn_noreturn_has_return_expr, FuncLoc)) && (!ReturnsVoid || @@ -653,11 +659,9 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, } } - DiagnosticsEngine &Diags = S.getDiagnostics(); - // Short circuit for compilation speed. - if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) - return; + if (CD.checkDiagnostics(S, ReturnsVoid, HasNoReturn)) + return; SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc(); // cpu_dispatch functions permit empty function bodies for ICC compatibility. @@ -2708,17 +2712,16 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( } // Warning: check missing 'return' - if (P.enableCheckFallThrough) { + if (P.enableCheckFallThrough || S.getLangOpts().C2y) { const CheckFallThroughDiagnostics &CD = - (isa(D) - ? CheckFallThroughDiagnostics::MakeForBlock() - : (isa(D) && - cast(D)->getOverloadedOperator() == OO_Call && - cast(D)->getParent()->isLambda()) - ? CheckFallThroughDiagnostics::MakeForLambda() - : (fscope->isCoroutine() - ? CheckFallThroughDiagnostics::MakeForCoroutine(D) - : CheckFallThroughDiagnostics::MakeForFunction(D))); + (isa(D) ? CheckFallThroughDiagnostics::MakeForBlock() + : (isa(D) && + cast(D)->getOverloadedOperator() == OO_Call && + cast(D)->getParent()->isLambda()) + ? CheckFallThroughDiagnostics::MakeForLambda() + : (fscope->isCoroutine() + ? CheckFallThroughDiagnostics::MakeForCoroutine(D) + : CheckFallThroughDiagnostics::MakeForFunction(S, D))); CheckFallThroughForBody(S, D, Body, BlockType, CD, AC); } diff --git a/clang/test/C/C2y/n3262.c b/clang/test/C/C2y/n3262.c index 3ff2062d88dde..611458599c5d9 100644 --- a/clang/test/C/C2y/n3262.c +++ b/clang/test/C/C2y/n3262.c @@ -17,4 +17,4 @@ * copy is made and diagnosing on copy (or on use of the copied va_list). */ -int main() {} +int main() { return 0; } diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 5e1c12ba26d87..8f4a43a9c7b05 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -4327,7 +4327,9 @@ TEST_P(ASTMatchersTest, hasOperator) { } TEST_P(ASTMatchersTest, IsMain) { - EXPECT_TRUE(matches("int main() {}", functionDecl(isMain()))); + EXPECT_TRUE(matches("void main() { }", functionDecl(isMain()))); + + EXPECT_TRUE(matches("int main() { return 0; }", functionDecl(isMain()))); EXPECT_TRUE(notMatches("int main2() { return 0; }", functionDecl(isMain()))); } diff --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp index d58e190923a1f..166ccc21f4a8d 100644 --- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp @@ -96,6 +96,9 @@ INSTANTIATE_TEST_SUITE_P( }); TEST_P(BuildSyntaxTreeTest, Simple) { + if (GetParam().isC26OrLater()) { + return; + } EXPECT_TRUE(treeDumpEqual( R"cpp( int main() {}