From 78ecb8737d97a038770af9f6a1ad1d7925c87eb7 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 16 Oct 2014 20:13:28 +0000 Subject: [PATCH] No longer emit diagnostics about unused results (comparisons, etc) from unevaluated contexts. Fixes PR18571. llvm-svn: 219954 --- clang/lib/Sema/SemaStmt.cpp | 6 ++++ clang/test/SemaCXX/warn-unused-comparison.cpp | 2 ++ clang/test/SemaCXX/warn-unused-result.cpp | 47 ++++++++++++++++++++++++++ clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 16 +++++++++ 4 files changed, 71 insertions(+) create mode 100644 clang/test/SemaCXX/warn-unused-value-cxx11.cpp diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index c03ac86..7efcb2e 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -185,6 +185,12 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { const Expr *E = dyn_cast_or_null(S); if (!E) return; + + // If we are in an unevaluated expression context, then there can be no unused + // results because the results aren't expected to be used in the first place. + if (isUnevaluatedContext()) + return; + SourceLocation ExprLoc = E->IgnoreParens()->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/SemaCXX/warn-unused-comparison.cpp b/clang/test/SemaCXX/warn-unused-comparison.cpp index 3afad58..a24b5a2 100644 --- a/clang/test/SemaCXX/warn-unused-comparison.cpp +++ b/clang/test/SemaCXX/warn-unused-comparison.cpp @@ -83,6 +83,8 @@ void test() { #define EQ(x,y) (x) == (y) EQ(x, 5); #undef EQ + + (void)sizeof(1 < 2, true); // No warning; unevaluated context. } namespace PR10291 { diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp index 581af09..1af0a01 100644 --- a/clang/test/SemaCXX/warn-unused-result.cpp +++ b/clang/test/SemaCXX/warn-unused-result.cpp @@ -94,3 +94,50 @@ void Bar() { }; } + +namespace PR18571 { +// Unevaluated contexts should not trigger unused result warnings. +template +auto foo(T) -> decltype(f(), bool()) { // Should not warn. + return true; +} + +void g() { + foo(1); +} +} + +namespace std { +class type_info { }; +} + +namespace { +// The typeid expression operand is evaluated only when the expression type is +// a glvalue of polymorphic class type. + +struct B { + virtual void f() {} +}; + +struct D : B { + void f() override {} +}; + +struct C {}; + +void g() { + // The typeid expression operand is evaluated only when the expression type is + // a glvalue of polymorphic class type; otherwise the expression operand is not + // evaluated and should not trigger a diagnostic. + D d; + C c; + (void)typeid(f(), c); // Should not warn. + (void)typeid(f(), d); // expected-warning {{ignoring return value}} + + // The sizeof expression operand is never evaluated. + (void)sizeof(f(), c); // Should not warn. + + // The noexcept expression operand is never evaluated. + (void)noexcept(f(), false); // Should not warn. +} +} diff --git a/clang/test/SemaCXX/warn-unused-value-cxx11.cpp b/clang/test/SemaCXX/warn-unused-value-cxx11.cpp new file mode 100644 index 0000000..115ddf3 --- /dev/null +++ b/clang/test/SemaCXX/warn-unused-value-cxx11.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wunused-value %s +// expected-no-diagnostics + +void f() __attribute__((const)); + +namespace PR18571 { +// Unevaluated contexts should not trigger unused result warnings. +template +auto foo(T) -> decltype(f(), bool()) { // Should not warn. + return true; +} + +void g() { + foo(1); +} +} -- 2.7.4