diff options
author | Jason Merrill <jason@redhat.com> | 2003-12-19 15:25:22 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2003-12-19 15:25:22 -0500 |
commit | 60cd3e8bab61b02cee0d0c57e7e3eeb9e9672354 (patch) | |
tree | 13d28b960bbcfb9a2e460e83d58447d5ea93134b | |
parent | a0687c1fbcf51f8aec14b4bcbbf4cdd7c111be2c (diff) | |
download | gcc-60cd3e8bab61b02cee0d0c57e7e3eeb9e9672354.zip gcc-60cd3e8bab61b02cee0d0c57e7e3eeb9e9672354.tar.gz gcc-60cd3e8bab61b02cee0d0c57e7e3eeb9e9672354.tar.bz2 |
re PR c++/13371 (infinite loop with packed struct and inlining)
PR c++/13371
* typeck.c (build_modify_expr): Stabilize lhs if we're narrowing.
From-SVN: r74846
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/bitfield2.C | 33 |
3 files changed, 49 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ab064ba..6888140 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2003-12-19 Jason Merrill <jason@redhat.com> + + PR c++/13371 + * typeck.c (build_modify_expr): Stabilize lhs if we're narrowing. + 2003-12-18 Richard Henderson <rth@redhat.com> * cp-tree.h (struct lang_type_header): Remove __extension__. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 791ba21..56810e5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4919,7 +4919,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) tree newrhs = rhs; tree lhstype = TREE_TYPE (lhs); tree olhstype = lhstype; - tree olhs = lhs; + tree olhs = NULL_TREE; /* Avoid duplicate error messages from operands that had errors. */ if (lhs == error_mark_node || rhs == error_mark_node) @@ -5149,6 +5149,15 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (lhstype != TREE_TYPE (lhs)) { + /* Avoid warnings converting integral types back into enums for + enum bit fields. */ + if (TREE_CODE (lhstype) == INTEGER_TYPE + && TREE_CODE (olhstype) == ENUMERAL_TYPE) + { + if (TREE_SIDE_EFFECTS (lhs)) + lhs = stabilize_reference (lhs); + olhs = lhs; + } lhs = copy_node (lhs); TREE_TYPE (lhs) = lhstype; } @@ -5221,10 +5230,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (olhstype == TREE_TYPE (result)) return result; - /* Avoid warnings converting integral types back into enums - for enum bit fields. */ - if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE - && TREE_CODE (olhstype) == ENUMERAL_TYPE) + if (olhs) { result = build (COMPOUND_EXPR, olhstype, result, olhs); TREE_NO_UNUSED_WARNING (result) = 1; diff --git a/gcc/testsuite/g++.dg/init/bitfield2.C b/gcc/testsuite/g++.dg/init/bitfield2.C new file mode 100644 index 0000000..e54b2e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/bitfield2.C @@ -0,0 +1,33 @@ +// PR c++/13371 +// Bug: We were failing to properly protect the lhs on the line marked +// "here" from multiple evaluation. + +// { dg-do run } + +extern "C" int printf (const char *, ...); + +enum E { E1, E2 }; + +struct A +{ + E e : 8; + unsigned char c; +}; + +A ar[2]; + +int c; + +int f() +{ + ++c; + printf ("f()\n"); + return 0; +} + +int main() +{ + ar[0].c = 0xff; + ar[f()].e = E1; // here + return (c != 1 || ar[0].c != 0xff); +} |