From: Jason Merrill Date: Fri, 19 Dec 2003 20:25:22 +0000 (-0500) Subject: re PR c++/13371 (infinite loop with packed struct and inlining) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=60cd3e8bab61b02cee0d0c57e7e3eeb9e9672354;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ab064baa71d..68881403976 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2003-12-19 Jason Merrill + + PR c++/13371 + * typeck.c (build_modify_expr): Stabilize lhs if we're narrowing. + 2003-12-18 Richard Henderson * cp-tree.h (struct lang_type_header): Remove __extension__. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 791ba210b15..56810e5c0b3 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 00000000000..e54b2e423fb --- /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); +}