Author: Aditya Singh Date: 2023-03-27T14:47:08-04:00 New Revision: dedd7b6548f4a37f4f691aa0cd3a709756b7e794
URL: https://github.com/llvm/llvm-project/commit/dedd7b6548f4a37f4f691aa0cd3a709756b7e794 DIFF: https://github.com/llvm/llvm-project/commit/dedd7b6548f4a37f4f691aa0cd3a709756b7e794.diff LOG: Added checking for completeness of lvalue in conditional operator Given: ``` struct x y; int main(void) { (void)(1 ? y : y); } struct x {int i;}; ``` The conditional operator(?:) requires the second and third operands to be of compatible types. To be compatible, they also need to be complete (however, both can be void). Therefore, the expected response from clang after running the above code as a C program should be error dialogue pointing out that both the types are incomplete hence incompatible, but the code compiled without any errors. The patch ensures the completeness in the CheckCondtionalOperand function present in llvm-project/clang/lib/Sema/SemaChecking.cpp. Fixes https://github.com/llvm/llvm-project/issues/59718 Differential Revision: https://reviews.llvm.org/D144358 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaChecking.cpp clang/test/Sema/incomplete-decl.c Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b2efa99313255..295532a9bfeca 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -186,6 +186,9 @@ Improvements to Clang's diagnostics by prioritizing ``-Wunreachable-code-fallthrough``. - Clang now correctly diagnoses statement attributes ``[[clang::always_inine]]`` and ``[[clang::noinline]]`` when used on a statement with dependent call expressions. +- Clang now checks for completeness of the second and third arguments in the + conditional operator. + (`#59718 <https://github.com/llvm/llvm-project/issues/59718>`_) Bug Fixes in This Version ------------------------- diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a3f2452b53d0c..c8b42519c88dc 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14396,6 +14396,9 @@ static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext) { E = E->IgnoreParenImpCasts(); + // Diagnose incomplete type for second or third operand in C. + if (!S.getLangOpts().CPlusPlus && E->getType()->isRecordType()) + S.RequireCompleteExprType(E, diag::err_incomplete_type); if (auto *CO = dyn_cast<AbstractConditionalOperator>(E)) return CheckConditionalOperator(S, CO, CC, T); diff --git a/clang/test/Sema/incomplete-decl.c b/clang/test/Sema/incomplete-decl.c index 954d4ab0c672f..bf2890bba9911 100644 --- a/clang/test/Sema/incomplete-decl.c +++ b/clang/test/Sema/incomplete-decl.c @@ -1,31 +1,51 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify=c,expected %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=cxx,expected %s -struct foo; // expected-note 5 {{forward declaration of 'struct foo'}} + + +struct foo; // c-note 5 {{forward declaration of 'struct foo'}} \ + cxx-note 3 {{forward declaration of 'foo'}} void b; // expected-error {{variable has incomplete type 'void'}} -struct foo f; // expected-error{{tentative definition has type 'struct foo' that is never completed}} +struct foo f; // c-error {{tentative definition has type 'struct foo' that is never completed}} \ + cxx-error {{variable has incomplete type 'struct foo'}} static void c; // expected-error {{variable has incomplete type 'void'}} -static struct foo g; // expected-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \ - expected-error{{tentative definition has type 'struct foo' that is never completed}} +static struct foo g; // c-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \ + c-error {{tentative definition has type 'struct foo' that is never completed}} \ + cxx-error {{variable has incomplete type 'struct foo'}} -extern void d; +extern void d; // cxx-error {{variable has incomplete type 'void'}} extern struct foo e; -int ary[]; // expected-warning {{tentative array definition assumed to have one element}} -struct foo bary[]; // expected-error {{array has incomplete element type 'struct foo'}} +int ary[]; // c-warning {{tentative array definition assumed to have one element}} \ + cxx-error {{definition of variable with array type needs an explicit size or an initializer}} +struct foo bary[]; // c-error {{array has incomplete element type 'struct foo'}} \ + cxx-error {{definition of variable with array type needs an explicit size or an initializer}} void func(void) { - int ary[]; // expected-error{{definition of variable with array type needs an explicit size or an initializer}} + int ary[]; // expected-error {{definition of variable with array type needs an explicit size or an initializer}} void b; // expected-error {{variable has incomplete type 'void'}} struct foo f; // expected-error {{variable has incomplete type 'struct foo'}} } -int h[]; // expected-warning {{tentative array definition assumed to have one element}} -int (*i)[] = &h+1; // expected-error {{arithmetic on a pointer to an incomplete type 'int[]'}} +int h[]; // c-warning {{tentative array definition assumed to have one element}} \ + cxx-error {{definition of variable with array type needs an explicit size or an initializer}} +int (*i)[] = &h+1; // c-error {{arithmetic on a pointer to an incomplete type 'int[]'}} struct bar j = {1}; // expected-error {{variable has incomplete type 'struct bar'}} \ - expected-note {{forward declaration of 'struct bar'}} -struct bar k; + c-note {{forward declaration of 'struct bar'}} \ + cxx-note 2 {{forward declaration of 'bar'}} + +struct bar k; // cxx-error {{variable has incomplete type 'struct bar'}} struct bar { int a; }; +struct x y; //c-note 2 {{forward declaration of 'struct x'}} \ + cxx-error {{variable has incomplete type 'struct x'}} \ + cxx-note {{forward declaration of 'x'}} +void foo() { + (void)(1 ? y : y); // c-error 2 {{incomplete type 'struct x' where a complete type is required}} +} +struct x{ + int a; +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits