Skip to content

Proof of concept for N3483 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Testing/TestClangConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
39 changes: 21 additions & 18 deletions clang/lib/Sema/AnalysisBasedWarnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 ||
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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<BlockDecl>(D)
? CheckFallThroughDiagnostics::MakeForBlock()
: (isa<CXXMethodDecl>(D) &&
cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
cast<CXXMethodDecl>(D)->getParent()->isLambda())
? CheckFallThroughDiagnostics::MakeForLambda()
: (fscope->isCoroutine()
? CheckFallThroughDiagnostics::MakeForCoroutine(D)
: CheckFallThroughDiagnostics::MakeForFunction(D)));
(isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
: (isa<CXXMethodDecl>(D) &&
cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
cast<CXXMethodDecl>(D)->getParent()->isLambda())
? CheckFallThroughDiagnostics::MakeForLambda()
: (fscope->isCoroutine()
? CheckFallThroughDiagnostics::MakeForCoroutine(D)
: CheckFallThroughDiagnostics::MakeForFunction(S, D)));
CheckFallThroughForBody(S, D, Body, BlockType, CD, AC);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/C/C2y/n3262.c
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
4 changes: 3 additions & 1 deletion clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())));
}
Expand Down
3 changes: 3 additions & 0 deletions clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ INSTANTIATE_TEST_SUITE_P(
});

TEST_P(BuildSyntaxTreeTest, Simple) {
if (GetParam().isC26OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
int main() {}
Expand Down