Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -195,7 +195,7 @@ if (isUnevaluatedContext()) return; - SourceLocation ExprLoc = E->IgnoreParens()->getExprLoc(); + 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 // expression is a call to a function with the warn_unused_result attribute, @@ -218,6 +218,16 @@ if (isa(E) && Loc.isMacroID()) return; + // Check if this is the UNREFERENCED_PARAMETER from the Microsoft headers. + // That macro is frequently used to suppress "unused parameter" warnings, + // but its implementation makes clang's -Wunused-value fire. Prevent this. + if (getLangOpts().MSVCCompat && isa(E->IgnoreImpCasts()) && + Loc.isMacroID()) { + SourceLocation SpellLoc = Loc; + if (findMacroSpelling(SpellLoc, "UNREFERENCED_PARAMETER")) + return; + } + // Okay, we have an unused result. Depending on what the base expression is, // we might want to make a more specific diagnostic. Check for one of these // cases now. Index: test/Sema/unused-expr.c =================================================================== --- test/Sema/unused-expr.c +++ test/Sema/unused-expr.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unreachable-code +// RUN: %clang_cc1 -DMS_COMPAT -fms-compatibility -fsyntax-only -verify %s -Wno-unreachable-code int foo(int X, int Y); @@ -156,3 +157,13 @@ #undef M5 #undef M6 #undef M7 + +#define UNREFERENCED_PARAMETER(x) (x) + +void unused_parm(int a) { +#ifdef MS_COMPAT + UNREFERENCED_PARAMETER(a); +#else + UNREFERENCED_PARAMETER(a); // expected-warning {{expression result unused}} +#endif +}