https://github.com/bala-bhargav updated https://github.com/llvm/llvm-project/pull/178661
>From 1d714597e5ddf4323e10fa7a2a7d832139518bab Mon Sep 17 00:00:00 2001 From: bhargav <[email protected]> Date: Thu, 29 Jan 2026 22:20:31 +0530 Subject: [PATCH 1/2] [clang-repl] Suppress [[nodiscard]] warnings for REPL printed expressions In clang-repl, expressions without semicolons have their values printed by the value printing mechanism. Since the result is used (for printing), we should not emit [[nodiscard]] warnings for these expressions. This fixes the false positive warning when evaluating expressions like v.size() in the REPL. [clang-repl] Suppress [[nodiscard]] warnings for printed expressions Fixes #178595 In clang-repl, expressions typed without a semicolon have their values printed. This means the return value is actually being used, not discarded. This fix suppresses [[nodiscard]] warnings for expressions that will be printed, while still emitting warnings for expressions with semicolons where the value is truly discarded# --- clang/lib/Parse/ParseDecl.cpp | 4 ++++ clang/lib/Sema/SemaStmt.cpp | 9 +++++++++ clang/test/Interpreter/nodiscard.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 clang/test/Interpreter/nodiscard.cpp diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index df9e3878bffc0..59280f5ad8d29 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5721,6 +5721,10 @@ Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() { Tok.getAnnotationValue() != nullptr) { ConsumeAnnotationToken(); TLSD->setSemiMissing(); + } else if (R.isUsable()) { + // Semicolon is present, so the value is being discarded. + // Re-diagnose [[nodiscard]] warnings that were suppressed during parsing. + Actions.DiagnoseUnusedExprResult(R.get(), diag::warn_unused_expr); } SmallVector<Decl *, 2> DeclsInGroup; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 5ab10fdfc7b74..4267f1a360d4a 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -239,6 +239,15 @@ void DiagnoseUnused(Sema &S, const Expr *E, std::optional<unsigned> DiagID) { if (S.isUnevaluatedContext()) return; + // In incremental processing mode (REPL), expressions inside TopLevelStmtDecl + // without a semicolon will have their values printed by the value printing + // mechanism. The result is therefore "used" and we should not warn about + // [[nodiscard]] attributes. + if (S.PP.isIncrementalProcessingEnabled()) { + if (isa<TopLevelStmtDecl>(S.CurContext)) + return; + } + SourceLocation ExprLoc = E->IgnoreParenImpCasts()->getExprLoc(); // In most cases, we don't want to warn if the expression is written in a // macro body, or if the macro comes from a system header. If the offending diff --git a/clang/test/Interpreter/nodiscard.cpp b/clang/test/Interpreter/nodiscard.cpp new file mode 100644 index 0000000000000..154e8ae39f618 --- /dev/null +++ b/clang/test/Interpreter/nodiscard.cpp @@ -0,0 +1,25 @@ +// REQUIRES: host-supports-jit +// RUN: cat %s | clang-repl 2>&1 | FileCheck %s + +// Test that [[nodiscard]] warnings are suppressed for REPL top-level +// expressions that will have their values printed (no semicolon), +// but are still emitted when the value is actually discarded (with semicolon). + +extern "C" int printf(const char*,...); + +[[nodiscard]] int getValue() { return 42; } + +// Negative test: Warning when value is discarded (with semicolon) +getValue(); +// CHECK: warning: ignoring return value of function declared with 'nodiscard' attribute + +// Positive test: No warning when expression value is printed (no semicolon) +getValue() +// CHECK: (int) 42 + +// Verify assignment doesn't warn +int x = getValue(); +printf("x = %d\n", x); +// CHECK: x = 42 + +%quit >From e022d15f052e29f0029e97708acf056d7e21dcd5 Mon Sep 17 00:00:00 2001 From: bhargav <[email protected]> Date: Fri, 30 Jan 2026 10:09:09 +0530 Subject: [PATCH 2/2] [clang-repl] Fix [[nodiscard]] warning handling based on reviewer feedback - Remove special case from SemaStmt.cpp as suggested by reviewer - Suppress warn_unused_result in Interpreter.cpp during parsing - Re-enable and diagnose [[nodiscard]] warnings in ParseDecl.cpp when semicolon is present Fixes #178595 --- clang/lib/Interpreter/Interpreter.cpp | 6 ++++++ clang/lib/Parse/ParseDecl.cpp | 5 ++++- clang/lib/Sema/SemaStmt.cpp | 9 --------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 9c94cfa5ee381..3eef722541eb8 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -469,6 +469,12 @@ Interpreter::Parse(llvm::StringRef Code) { // printing could cause it. getCompilerInstance()->getDiagnostics().setSeverity( clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation()); + // Suppress [[nodiscard]] warnings during parsing since we don't know yet + // if the expression has a missing semicolon (value printed) or not. + // If the value is printed, it's considered "used" so no warning is needed. + getCompilerInstance()->getDiagnostics().setSeverity( + clang::diag::warn_unused_result, diag::Severity::Ignored, + SourceLocation()); llvm::Expected<TranslationUnitDecl *> TuOrErr = IncrParser->Parse(Code); if (!TuOrErr) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 59280f5ad8d29..70381195e33a3 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5721,9 +5721,12 @@ Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() { Tok.getAnnotationValue() != nullptr) { ConsumeAnnotationToken(); TLSD->setSemiMissing(); + // Expression result will be printed, so it's "used" - no warning needed. } else if (R.isUsable()) { // Semicolon is present, so the value is being discarded. - // Re-diagnose [[nodiscard]] warnings that were suppressed during parsing. + // Re-enable [[nodiscard]] warning and diagnose. + PP.getDiagnostics().setSeverity(diag::warn_unused_result, + diag::Severity::Warning, SourceLocation()); Actions.DiagnoseUnusedExprResult(R.get(), diag::warn_unused_expr); } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 4267f1a360d4a..5ab10fdfc7b74 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -239,15 +239,6 @@ void DiagnoseUnused(Sema &S, const Expr *E, std::optional<unsigned> DiagID) { if (S.isUnevaluatedContext()) return; - // In incremental processing mode (REPL), expressions inside TopLevelStmtDecl - // without a semicolon will have their values printed by the value printing - // mechanism. The result is therefore "used" and we should not warn about - // [[nodiscard]] attributes. - if (S.PP.isIncrementalProcessingEnabled()) { - if (isa<TopLevelStmtDecl>(S.CurContext)) - return; - } - SourceLocation ExprLoc = E->IgnoreParenImpCasts()->getExprLoc(); // In most cases, we don't want to warn if the expression is written in a // macro body, or if the macro comes from a system header. If the offending _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
