[Sema] fix false -Wcomma being emitted from void returning functions

Fixes https://github.com/llvm/llvm-project/issues/57151

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D131892
This commit is contained in:
YingChi Long 2022-08-15 22:35:39 +08:00
parent 05ac82de40
commit ccbc22cd89
No known key found for this signature in database
GPG Key ID: 7C4D5D7BA816DE62
3 changed files with 49 additions and 4 deletions

View File

@ -73,7 +73,8 @@ Bug Fixes
number of arguments cause an assertion fault.
- Fix multi-level pack expansion of undeclared function parameters.
This fixes `Issue 56094 <https://github.com/llvm/llvm-project/issues/56094>`_.
- Fix `#57151 <https://github.com/llvm/llvm-project/issues/57151>`_.
``-Wcomma`` is emitted for void returning functions.
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -13957,8 +13957,10 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
return getLangOpts().CPlusPlus ? LHSType : LHSType.getAtomicUnqualifiedType();
}
// Only ignore explicit casts to void.
static bool IgnoreCommaOperand(const Expr *E) {
// Scenarios to ignore if expression E is:
// 1. an explicit cast expression into void
// 2. a function call expression that returns void
static bool IgnoreCommaOperand(const Expr *E, const ASTContext &Context) {
E = E->IgnoreParens();
if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
@ -13973,6 +13975,8 @@ static bool IgnoreCommaOperand(const Expr *E) {
}
}
if (const auto *CE = dyn_cast<CallExpr>(E))
return CE->getCallReturnType(Context)->isVoidType();
return false;
}
@ -14014,7 +14018,7 @@ void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) {
}
// Only allow some expressions on LHS to not warn.
if (IgnoreCommaOperand(LHS))
if (IgnoreCommaOperand(LHS, Context))
return;
Diag(Loc, diag::warn_comma_operator);

View File

@ -140,6 +140,27 @@ void test_nested_fixits(void) {
// CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
}
void void_func();
int int_func() { return 0; }
void void_function_comma(){
void_func(), int_func(); // expected no -Wcomma because of the returning type `void`
// Reported by https://github.com/llvm/llvm-project/issues/57151
// Descriptions about -Wcomma: https://reviews.llvm.org/D3976
}
typedef void Void;
Void typedef_func();
void whatever() {
// We don't get confused about type aliases.
typedef_func(), int_func();
// Even function pointers don't confuse us.
void (*fp)() = void_func;
fp(), int_func();
}
#ifdef __cplusplus
class S2 {
public:
@ -296,4 +317,23 @@ void test_dependent_cast() {
(void)T{}, 0;
static_cast<void>(T{}), 0;
}
namespace {
// issue #57151
struct S {
void mem() {}
};
void whatever() {
struct S s;
// Member function calls also work as expected.
s.mem(), int_func();
// As do lambda calls.
[]() { return; }(), int_func();
}
} // namespace
#endif // ifdef __cplusplus