[PATCH] D64678: [Sema] Fix -Wuninitialized for struct assignment from GNU C statement expression

2019-07-26 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-24 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-24 Thread Aaron Ballman via Phabricator via cfe-commits
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

2019-07-23 Thread Nick Desaulniers via Phabricator via cfe-commits
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

2019-07-22 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-17 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
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

2019-07-15 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-15 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-15 Thread Nick Desaulniers via Phabricator via cfe-commits
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

2019-07-12 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-12 Thread Nick Desaulniers via Phabricator via cfe-commits
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

2019-07-12 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-12 Thread Nathan Huckleberry via Phabricator via cfe-commits
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

2019-07-12 Thread Nathan Huckleberry via Phabricator via cfe-commits
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