From: John McCall Date: Tue, 12 Oct 2010 07:14:40 +0000 (+0000) Subject: C's comma operator performs lvalue conversion on both its operands; X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cf2e5063ae7e7ed3f8d86bb426b2208e242128ab;p=clang C's comma operator performs lvalue conversion on both its operands; require them to have complete types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116297 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 52ab62be02..514d9ba3f2 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -6164,13 +6164,18 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, QualType Sema::CheckCommaOperands(Expr *LHS, Expr *&RHS, SourceLocation Loc) { DiagnoseUnusedExprResult(LHS); - // Comma performs lvalue conversion (C99 6.3.2.1), but not unary conversions. - // C++ does not perform this conversion (C++ [expr.comma]p1). - if (!getLangOptions().CPlusPlus) - DefaultFunctionArrayLvalueConversion(RHS); + // C's comma performs lvalue conversion (C99 6.3.2.1) on both its + // operands, but not unary promotions. + // C++'s comma does not do any conversions at all (C++ [expr.comma]p1). + if (!getLangOptions().CPlusPlus) { + DefaultFunctionArrayLvalueConversion(LHS); + if (!LHS->getType()->isVoidType()) + RequireCompleteType(Loc, LHS->getType(), diag::err_incomplete_type); - // FIXME: Check that RHS type is complete in C mode (it's legal for it to be - // incomplete in C++). + DefaultFunctionArrayLvalueConversion(RHS); + if (!RHS->getType()->isVoidType()) + RequireCompleteType(Loc, RHS->getType(), diag::err_incomplete_type); + } return RHS->getType(); } diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index 56a52bed1b..d6e17ff6ec 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -150,3 +150,10 @@ int test20(int x) { // no warning, this is an idiom for "true" in old C style. return x && (signed char)1; } + +struct Test21; // expected-note 2 {{forward declaration}} +void test21(volatile struct Test21 *ptr) { + void test21_help(void); + (test21_help(), *ptr); // expected-error {{incomplete type 'struct Test21' where a complete type is required}} + (*ptr, test21_help()); // expected-error {{incomplete type 'struct Test21' where a complete type is required}} +}