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
};
}
+
+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.
+}
+}
--- /dev/null
+// 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);
+}
+}