[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
This revision was automatically updated to reflect the committed changes. Closed by commit rL367134: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression (authored by Nathan-Huckleberry, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D64678?vs=211545&id=211966#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c Index: cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c === --- cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c +++ cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); + struct widget a = (init2(&a), a); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: cfe/trunk/lib/Sema/SemaDecl.cpp === --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -11257,9 +11257,12 @@ // Check for self-references within variable initializers. // Variables declared within a function/method body (except for references) // are handled by a dataflow analysis. - if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || - VDecl->getType()->isReferenceType()) { -CheckSelfReference(*this, RealDecl, Init, DirectInit); + // This is undefined behavior in C++, but valid in C. + if (getLangOpts().CPlusPlus) { +if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || +VDecl->getType()->isReferenceType()) { + CheckSelfReference(*this, RealDecl, Init, DirectInit); +} } // If the type changed, it means we had an incomplete type that was Index: cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c === --- cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c +++ cfe/trunk/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); + struct widget a = (init2(&a), a); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: cfe/trunk/lib/Sema/SemaDecl.cpp === --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -11257,9 +11257,12 @@ // Check for self-references within variable initializers. // Variables declared within a function/method body (except for references) // are handled by a dataflow analysis. - if (!VDecl->ha
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry updated this revision to Diff 211545. Nathan-Huckleberry added a comment. - Add comment Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); + struct widget a = (init2(&a), a); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -11255,9 +11255,12 @@ // Check for self-references within variable initializers. // Variables declared within a function/method body (except for references) // are handled by a dataflow analysis. - if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || - VDecl->getType()->isReferenceType()) { -CheckSelfReference(*this, RealDecl, Init, DirectInit); + // This is undefined behavior in C++, but valid in C. + if (getLangOpts().CPlusPlus) { +if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || +VDecl->getType()->isReferenceType()) { + CheckSelfReference(*this, RealDecl, Init, DirectInit); +} } // If the type changed, it means we had an incomplete type that was Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); + struct widget a = (init2(&a), a); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -11255,9 +11255,12 @@ // Check for self-references within variable initializers. // Variables declared within a function/method body (except for references) // are handled by a dataflow analysis. - if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || - VDecl->getType()->isReferenceType()) { -CheckSelfReference(*this, RealDecl, Init, DirectInit); + // This is undefined behavior in C++, but valid in C. + if (getLangOpts().CPlusPlus) { +if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || +VDecl->getType()->isReferenceType()) { + CheckSelfReference(*this, RealDec
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
aaron.ballman accepted this revision. aaron.ballman added a comment. LGTM aside from a comment request. Comment at: clang/lib/Sema/SemaDecl.cpp:11258 // are handled by a dataflow analysis. - if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || - VDecl->getType()->isReferenceType()) { -CheckSelfReference(*this, RealDecl, Init, DirectInit); + if (getLangOpts().CPlusPlus) { +if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || This should probably have a comment explaining why we only do it in C++ mode. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
nickdesaulniers accepted this revision. nickdesaulniers added a comment. This revision is now accepted and ready to land. Thanks for the patch and following up on the review. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry updated this revision to Diff 211230. Nathan-Huckleberry added a comment. - Disable self reference checking for C Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); + struct widget a = (init2(&a), a); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -11255,9 +11255,11 @@ // Check for self-references within variable initializers. // Variables declared within a function/method body (except for references) // are handled by a dataflow analysis. - if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || - VDecl->getType()->isReferenceType()) { -CheckSelfReference(*this, RealDecl, Init, DirectInit); + if (getLangOpts().CPlusPlus) { +if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || +VDecl->getType()->isReferenceType()) { + CheckSelfReference(*this, RealDecl, Init, DirectInit); +} } // If the type changed, it means we had an incomplete type that was Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); + struct widget a = (init2(&a), a); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -11255,9 +11255,11 @@ // Check for self-references within variable initializers. // Variables declared within a function/method body (except for references) // are handled by a dataflow analysis. - if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || - VDecl->getType()->isReferenceType()) { -CheckSelfReference(*this, RealDecl, Init, DirectInit); + if (getLangOpts().CPlusPlus) { +if (!VDecl->hasLocalStorage() || VDecl->getType()->isRecordType() || +VDecl->getType()->isReferenceType()) { + CheckSelfReference(*this, RealDecl, Init, DirectInit); +} } // If the type changed, it means we had an incomp
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
rsmith added a comment. I don't think this problem really has anything to do with statement expressions; consider: struct Widget a = (init2(&a), a); ... which has the same behaviour and presumably produces the same warning. It's just a C / C++ difference. In C++, these examples are undefined because the lifetime of the object hasn't started yet, but I think in C they're valid. We should just disable the whole warning in C mode and leave it to the CFG analysis. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry marked 3 inline comments as done. Nathan-Huckleberry added inline comments. Comment at: clang/test/Sema/warn-uninitialized-statement-expression.c:21 +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); nickdesaulniers wrote: > This needs a trailing comment like: > ``` > int x = my_widget.x; // fixme: we should probably warn about this case > ``` > and file a bug about it. Doesn't need to be solved here. https://bugs.llvm.org/show_bug.cgi?id=42625 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry updated this revision to Diff 209905. Nathan-Huckleberry marked 3 inline comments as done. Nathan-Huckleberry added a comment. - Change cast type Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,11 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,11 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
nickdesaulniers added inline comments. Comment at: clang/lib/Sema/SemaDecl.cpp:10890 +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast_or_null(E)) { + return; Should just be `dyn_cast(E)`? http://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates Comment at: clang/test/Sema/warn-uninitialized-statement-expression.c:35 +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); Can you please file a bug pointing to this test case? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry updated this revision to Diff 209644. Nathan-Huckleberry added a comment. - Add warning-free test cases Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,11 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast_or_null(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +init(&i); +i; + }); +} + +void foo_bad(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +init2(&my_widget); +my_widget; + }); +} + +void bar_bad(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; //FIXME: There should be an uninitialized warning here +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,11 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast_or_null(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
nickdesaulniers added a comment. Thanks for the patch. Minor nits looking for test cases that should have no warning (like the two examples provided in the bug). Comment at: clang/test/Sema/warn-uninitialized-statement-expression.c:7 + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); Can you please add a case like `foo` without `z` in it (so that no warnings are expected, as in pr42604)? (You can keep both test cases, just looking for 1 more, as the first case). Comment at: clang/test/Sema/warn-uninitialized-statement-expression.c:20 + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; Ditto about adding a clear case that should not warn. Comment at: clang/test/Sema/warn-uninitialized-statement-expression.c:21 +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); This needs a trailing comment like: ``` int x = my_widget.x; // fixme: we should probably warn about this case ``` and file a bug about it. Doesn't need to be solved here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry updated this revision to Diff 209637. Nathan-Huckleberry added a comment. - Fixed style Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,11 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast_or_null(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int *); + +void foo(void) { + int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; + }); +} + +struct widget { + int x, y; +}; +void init2(struct widget *); + +void bar(void) { + struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); +my_widget; + }); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget *a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,11 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && +dyn_cast_or_null(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry updated this revision to Diff 209636. Nathan-Huckleberry added a comment. - Adding fix Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64678/new/ https://reviews.llvm.org/D64678 Files: clang/lib/Sema/SemaDecl.cpp clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int*); + +void foo(void) { +int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; +}); +} + +struct widget { +int x, y; +}; +void init2(struct widget*); + +void bar(void) { +struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); +my_widget; +}); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget* a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,10 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && dyn_cast_or_null(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int*); + +void foo(void) { +int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; +}); +} + +struct widget { +int x, y; +}; +void init2(struct widget*); + +void bar(void) { +struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); +my_widget; +}); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget* a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -10886,6 +10886,10 @@ if (DRE->getDecl() == OrigDecl) return; +if (cast(OrigDecl)->getType()->isRecordType() && dyn_cast_or_null(E)) { + return; +} + SelfReferenceChecker(S, OrigDecl).CheckExpr(E); } } // end anonymous namespace ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression
Nathan-Huckleberry created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Do not automatically self references of structs in statement expression as warnings. Instead wait for uninitialized cfg analysis. https://bugs.llvm.org/show_bug.cgi?id=42604 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D64678 Files: clang/test/Sema/warn-uninitialized-statement-expression.c Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int*); + +void foo(void) { +int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; +}); +} + +struct widget { +int x, y; +}; +void init2(struct widget*); + +void bar(void) { +struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); +my_widget; +}); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget* a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} Index: clang/test/Sema/warn-uninitialized-statement-expression.c === --- /dev/null +++ clang/test/Sema/warn-uninitialized-statement-expression.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -verify %s + +void init(int*); + +void foo(void) { +int i = ({ +int z = i; // expected-warning{{variable 'i' is uninitialized when used within its own initialization}} +init(&i); +i; +}); +} + +struct widget { +int x, y; +}; +void init2(struct widget*); + +void bar(void) { +struct widget my_widget = ({ +struct widget z = my_widget; // expected-warning{{variable 'my_widget' is uninitialized when used within its own initialization}} +int x = my_widget.x; +init2(&my_widget); +my_widget; +}); +} + +void baz(void) { + struct widget a = ({ +struct widget b = ({ + b = a; // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +}); +a; + }); +} + +void f(void) { + struct widget* a = ({ +init2(a); // expected-warning{{variable 'a' is uninitialized when used within its own initialization}} +a; + }); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits