diff options
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unused-comparison.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unused-result.cpp | 47 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 16 |
4 files changed, 71 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index c03ac86de05..7efcb2e9c49 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<Expr>(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 3afad585b66..a24b5a29a3d 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 581af09080d..1af0a0160a8 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 <typename T> +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 00000000000..115ddf3e02d --- /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 <typename T> +auto foo(T) -> decltype(f(), bool()) { // Should not warn. + return true; +} + +void g() { + foo(1); +} +} |