[clang] [Clang][Sema] Emit warnings for non-dependent expressions in dependent context regardless of reachability (PR #159364)
Yanzuo Liu via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 26 01:44:15 PST 2025
https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/159364
>From 03be74ad3d52cb775f75452354511662a83ab01d Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <zwuis at outlook.com>
Date: Fri, 26 Dec 2025 17:37:44 +0800
Subject: [PATCH] Emit warnings for non-dependent expressions in dependent
context regardless of reachability
---
clang/docs/ReleaseNotes.rst | 2 +
clang/lib/Sema/AnalysisBasedWarnings.cpp | 12 +++++-
clang/lib/Sema/SemaDecl.cpp | 8 +++-
clang/test/SemaCXX/warn-unsequenced.cpp | 4 +-
clang/test/SemaCXX/warn-unused-value.cpp | 49 ++++++++++++++++++++++++
5 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2319ff13f7864..78662752ea748 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -498,6 +498,8 @@ Improvements to Clang's diagnostics
- Clang now generates a fix-it for C++20 designated initializers when the
initializers do not match the declaration order in the structure.
+- Now more analysis-based warnings are emitted before template instantiation.
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 7b08648080710..8ee2fbe2c3ce3 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2989,9 +2989,17 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
S.SourceMgr.isInSystemHeader(D->getLocation())))
return;
- // For code in dependent contexts, we'll do this at instantiation time.
- if (cast<DeclContext>(D)->isDependentContext())
+ // For instantiation-dependent exprs, we'll do this at instantiation time.
+ if (cast<DeclContext>(D)->isDependentContext()) {
+ for (const auto &[PD, Loc, Stmts] : fscope->PossiblyUnreachableDiags)
+ if (llvm::all_of(Stmts, [](const Stmt *S) {
+ const auto *E = dyn_cast<Expr>(S);
+ return E && !E->isInstantiationDependent();
+ }))
+ S.Diag(Loc, PD);
+
return;
+ }
if (S.hasUncompilableErrorOccurred()) {
// Flush out any possibly unreachable diagnostics.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 11323803e1910..98b9bdcaf13d9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16846,7 +16846,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
getDiagnostics().getSuppressAllDiagnostics()) {
DiscardCleanupsInEvaluationContext();
}
- if (!hasUncompilableErrorOccurred() && !isa<FunctionTemplateDecl>(dcl)) {
+ if (!hasUncompilableErrorOccurred()) {
// Since the body is valid, issue any analysis-based warnings that are
// enabled.
ActivePolicy = &WP;
@@ -16903,7 +16903,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
PopDeclContext();
if (!RetainFunctionScopeInfo)
- PopFunctionScopeInfo(ActivePolicy, dcl);
+ // If `dcl` is `FunctionTemplateDecl`, pass its corresponding
+ // `FunctionDecl`, otherwise (e.g., `ObjCMethodDecl`), pass `dcl`,
+ // so that we can emit some diagnostics in
+ // `AnalysisBasedWarnings::IssueWarnings()`
+ PopFunctionScopeInfo(ActivePolicy, FD ? FD : dcl);
// If any errors have occurred, clear out any temporaries that may have
// been leftover. This ensures that these temporaries won't be picked up for
// deletion in some later function.
diff --git a/clang/test/SemaCXX/warn-unsequenced.cpp b/clang/test/SemaCXX/warn-unsequenced.cpp
index 50dde8f3a5789..d47a4683f0fbe 100644
--- a/clang/test/SemaCXX/warn-unsequenced.cpp
+++ b/clang/test/SemaCXX/warn-unsequenced.cpp
@@ -782,8 +782,8 @@ int Foo<X>::Run() {
// cxx11-warning at -1 {{unsequenced modification and access to 'num'}}
foo(num++, num++);
- // cxx11-warning at -1 {{multiple unsequenced modifications to 'num'}}
- // cxx17-warning at -2 {{multiple unsequenced modifications to 'num'}}
+ // cxx11-warning at -1 2{{multiple unsequenced modifications to 'num'}}
+ // cxx17-warning at -2 2{{multiple unsequenced modifications to 'num'}}
return 1;
}
diff --git a/clang/test/SemaCXX/warn-unused-value.cpp b/clang/test/SemaCXX/warn-unused-value.cpp
index 2a07a0324f3f0..84f456c108279 100644
--- a/clang/test/SemaCXX/warn-unused-value.cpp
+++ b/clang/test/SemaCXX/warn-unused-value.cpp
@@ -178,3 +178,52 @@ auto b() {
}
} // namespace test6
#endif
+
+#if __cplusplus >= 201402L
+namespace test7 {
+auto L1 = [] {
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0;
+};
+auto L2 = [](auto) {
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+};
+
+void f1() {
+ auto L1 = [] {
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0;
+ };
+ auto L2 = [](auto) {
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ };
+
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0;
+}
+
+template <typename> void f2() {
+ auto L1 = [] {
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ };
+ auto L2 = [](auto) {
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ };
+
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+ return;
+ 0, 0; // expected-warning {{left operand of comma operator has no effect}}
+}
+}
+#endif
More information about the cfe-commits
mailing list