Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662, take 4)
OK, thanks. On Wed, May 9, 2018 at 4:49 PM, Jakub Jelinek wrote: > On Wed, May 09, 2018 at 11:01:18AM -0400, Jason Merrill wrote: >> On Wed, May 9, 2018 at 10:47 AM, Jakub Jelinek wrote: >> > On Wed, May 09, 2018 at 10:40:26AM -0400, Jason Merrill wrote: >> >> On Wed, May 9, 2018 at 4:55 AM, Jakub Jelinek wrote: >> >> > On Tue, May 08, 2018 at 11:28:18PM -0400, Jason Merrill wrote: >> >> >> Maybe add a type parameter that defaults to size_type_node... >> >> >> >> >> >> > + ret = fold_convert_loc (loc, TREE_TYPE (expr), >> >> >> > + fold_offsetof_1 (TREE_TYPE (expr), >> >> >> > op0)); >> >> >> >> >> >> ...and then this can be >> >> >> >> >> >> fold_offsetof (op0, TREE_TYPE (exp0)) >> >> > >> >> > Like this then? >> >> > >> >> > + ret = fold_convert_loc (loc, TREE_TYPE (expr), >> >> > + fold_offsetof (op0, TREE_TYPE (expr))); >> >> >> >> I was thinking that we then wouldn't need the fold_convert at the call >> >> sites anymore, either. >> > >> > The patch only converts to non-pointer types, I'm not sure if it is >> > desirable to do the same with pointer types (and most of the other callers >> > don't use convert, but fold_convert which is significantly different, the >> > former is emitting diagnostics, the latter is just an conversion + >> > optimization). >> >> Is there a reason we can't use fold_convert for the non-pointer case, >> too? I don't think we're interested in diagnostics from this >> particular call. > > This patch instead uses convert everywhere. Bootstrapped/regtested on > x86_64-linux and i686-linux, ok for trunk? > > 2018-05-09 Jakub Jelinek > > PR c++/85662 > * c-common.h (fold_offsetof_1): Removed. > (fold_offsetof): Add TYPE argument defaulted to size_type_node and > CTX argument defaulted to ERROR_MARK. > * c-common.c (fold_offsetof_1): Renamed to ... > (fold_offsetof): ... this. Remove wrapper function. Add TYPE > argument, convert the pointer constant to TYPE and use size_binop > with PLUS_EXPR instead of fold_build_pointer_plus if type is not > a pointer type. Adjust recursive calls. > > * c-fold.c (c_fully_fold_internal): Use fold_offsetof rather than > fold_offsetof_1, pass TREE_TYPE (expr) as TYPE to it and drop the > fold_convert_loc. > * c-typeck.c (build_unary_op): Use fold_offsetof rather than > fold_offsetof_1, pass argtype as TYPE to it and drop the > fold_convert_loc. > > * cp-gimplify.c (cp_fold): Use fold_offsetof rather than > fold_offsetof_1, pass TREE_TYPE (x) as TYPE to it and drop the > fold_convert. > > * g++.dg/ext/offsetof2.C: New test. > > --- gcc/c-family/c-common.h.jj 2018-05-09 20:12:25.845258371 +0200 > +++ gcc/c-family/c-common.h 2018-05-09 20:20:02.265649121 +0200 > @@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree); > > extern void verify_sequence_points (tree); > > -extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); > -extern tree fold_offsetof (tree); > +extern tree fold_offsetof (tree, tree = size_type_node, > + tree_code ctx = ERROR_MARK); > > extern int complete_array_type (tree *, tree, bool); > > --- gcc/c-family/c-common.c.jj 2018-05-09 20:12:25.763258297 +0200 > +++ gcc/c-family/c-common.c 2018-05-09 20:21:23.770718896 +0200 > @@ -6168,10 +6168,11 @@ c_common_to_target_charset (HOST_WIDE_IN > > /* Fold an offsetof-like expression. EXPR is a nested sequence of component > references with an INDIRECT_REF of a constant at the bottom; much like the > - traditional rendering of offsetof as a macro. Return the folded result. > */ > + traditional rendering of offsetof as a macro. TYPE is the desired type of > + the whole expression. Return the folded result. */ > > tree > -fold_offsetof_1 (tree expr, enum tree_code ctx) > +fold_offsetof (tree expr, tree type, enum tree_code ctx) > { >tree base, off, t; >tree_code code = TREE_CODE (expr); > @@ -6196,10 +6197,10 @@ fold_offsetof_1 (tree expr, enum tree_co > error ("cannot apply % to a non constant address"); > return error_mark_node; > } > - return TREE_OPERAND (expr, 0); > + return convert (type, TREE_OPERAND (expr, 0)); > > case COMPONENT_REF: > - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); > + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); >if (base == error_mark_node) > return base; > > @@ -6216,7 +6217,7 @@ fold_offsetof_1 (tree expr, enum tree_co >break; > > case ARRAY_REF: > - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); > + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); >if (base == error_mark_node) > return base; > > @@ -6273,23 +6274,16 @@ fold_offsetof_1 (tree expr, enum tree_co >/* Handle static members of volatil
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Wed, May 9, 2018 at 10:47 AM, Jakub Jelinek wrote: > On Wed, May 09, 2018 at 10:40:26AM -0400, Jason Merrill wrote: >> On Wed, May 9, 2018 at 4:55 AM, Jakub Jelinek wrote: >> > On Tue, May 08, 2018 at 11:28:18PM -0400, Jason Merrill wrote: >> >> Maybe add a type parameter that defaults to size_type_node... >> >> >> >> > + ret = fold_convert_loc (loc, TREE_TYPE (expr), >> >> > + fold_offsetof_1 (TREE_TYPE (expr), >> >> > op0)); >> >> >> >> ...and then this can be >> >> >> >> fold_offsetof (op0, TREE_TYPE (exp0)) >> > >> > Like this then? >> > >> > + ret = fold_convert_loc (loc, TREE_TYPE (expr), >> > + fold_offsetof (op0, TREE_TYPE (expr))); >> >> I was thinking that we then wouldn't need the fold_convert at the call >> sites anymore, either. > > The patch only converts to non-pointer types, I'm not sure if it is > desirable to do the same with pointer types (and most of the other callers > don't use convert, but fold_convert which is significantly different, the > former is emitting diagnostics, the latter is just an conversion + > optimization). Is there a reason we can't use fold_convert for the non-pointer case, too? I don't think we're interested in diagnostics from this particular call. Jason
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Wed, May 09, 2018 at 10:40:26AM -0400, Jason Merrill wrote: > On Wed, May 9, 2018 at 4:55 AM, Jakub Jelinek wrote: > > On Tue, May 08, 2018 at 11:28:18PM -0400, Jason Merrill wrote: > >> Maybe add a type parameter that defaults to size_type_node... > >> > >> > + ret = fold_convert_loc (loc, TREE_TYPE (expr), > >> > + fold_offsetof_1 (TREE_TYPE (expr), op0)); > >> > >> ...and then this can be > >> > >> fold_offsetof (op0, TREE_TYPE (exp0)) > > > > Like this then? > > > > + ret = fold_convert_loc (loc, TREE_TYPE (expr), > > + fold_offsetof (op0, TREE_TYPE (expr))); > > I was thinking that we then wouldn't need the fold_convert at the call > sites anymore, either. The patch only converts to non-pointer types, I'm not sure if it is desirable to do the same with pointer types (and most of the other callers don't use convert, but fold_convert which is significantly different, the former is emitting diagnostics, the latter is just an conversion + optimization). If it is ok to use the final pointer type rather than the initial one, but convert is not ok, then it would be something like: if (!POINTER_TYPE_P (type)) return convert (type, TREE_OPERAND (expr, 0)); else return fold_convert (type, TREE_OPERAND (expr, 0)); on the innermost constant and then indeed no conversion would be needed. Jakub
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Wed, May 9, 2018 at 4:55 AM, Jakub Jelinek wrote: > On Tue, May 08, 2018 at 11:28:18PM -0400, Jason Merrill wrote: >> Maybe add a type parameter that defaults to size_type_node... >> >> > + ret = fold_convert_loc (loc, TREE_TYPE (expr), >> > + fold_offsetof_1 (TREE_TYPE (expr), op0)); >> >> ...and then this can be >> >> fold_offsetof (op0, TREE_TYPE (exp0)) > > Like this then? > > + ret = fold_convert_loc (loc, TREE_TYPE (expr), > + fold_offsetof (op0, TREE_TYPE (expr))); I was thinking that we then wouldn't need the fold_convert at the call sites anymore, either. Jason
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Tue, May 08, 2018 at 11:28:18PM -0400, Jason Merrill wrote: > Maybe add a type parameter that defaults to size_type_node... > > > > > --- gcc/c/c-fold.c.jj 2018-01-17 22:00:12.310228253 +0100 > > +++ gcc/c/c-fold.c 2018-05-08 21:52:43.303940175 +0200 > > @@ -473,7 +473,8 @@ c_fully_fold_internal (tree expr, bool i > > && (op1 = get_base_address (op0)) != NULL_TREE > > && INDIRECT_REF_P (op1) > > && TREE_CONSTANT (TREE_OPERAND (op1, 0))) > > - ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 > > (op0)); > > + ret = fold_convert_loc (loc, TREE_TYPE (expr), > > + fold_offsetof_1 (TREE_TYPE (expr), op0)); > > ...and then this can be > > fold_offsetof (op0, TREE_TYPE (exp0)) Like this then? 2018-05-09 Jakub Jelinek PR c++/85662 * c-common.h (fold_offsetof_1): Removed. (fold_offsetof): Add TYPE argument defaulted to size_type_node and CTX argument defaulted to ERROR_MARK. * c-common.c (fold_offsetof_1): Renamed to ... (fold_offsetof): ... this. Remove wrapper function. Add TYPE argument, if it is not a pointer type, convert the pointer constant to TYPE and use size_binop with PLUS_EXPR instead of fold_build_pointer_plus. Adjust recursive calls. * c-fold.c (c_fully_fold_internal): Use fold_offsetof rather than fold_offsetof_1, pass TREE_TYPE (expr) as TYPE to it. * c-typeck.c (build_unary_op): Use fold_offsetof rather than fold_offsetof_1, pass argtype as TYPE to it. * cp-gimplify.c (cp_fold): Use fold_offsetof rather than fold_offsetof_1, pass TREE_TYPE (x) as TYPE to it. * g++.dg/ext/offsetof2.C: New test. --- gcc/c-family/c-common.h.jj 2018-05-06 23:12:49.185619717 +0200 +++ gcc/c-family/c-common.h 2018-05-09 10:28:20.149559265 +0200 @@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree); extern void verify_sequence_points (tree); -extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); -extern tree fold_offsetof (tree); +extern tree fold_offsetof (tree, tree = size_type_node, + tree_code ctx = ERROR_MARK); extern int complete_array_type (tree *, tree, bool); --- gcc/c-family/c-common.c.jj 2018-05-06 23:12:49.135619681 +0200 +++ gcc/c-family/c-common.c 2018-05-09 10:29:34.481650988 +0200 @@ -6168,10 +6168,12 @@ c_common_to_target_charset (HOST_WIDE_IN /* Fold an offsetof-like expression. EXPR is a nested sequence of component references with an INDIRECT_REF of a constant at the bottom; much like the - traditional rendering of offsetof as a macro. Return the folded result. */ + traditional rendering of offsetof as a macro. TYPE is the desired type of + the whole expression to which it will be converted afterwards. + Return the folded result. */ tree -fold_offsetof_1 (tree expr, enum tree_code ctx) +fold_offsetof (tree expr, tree type, enum tree_code ctx) { tree base, off, t; tree_code code = TREE_CODE (expr); @@ -6196,10 +6198,12 @@ fold_offsetof_1 (tree expr, enum tree_co error ("cannot apply % to a non constant address"); return error_mark_node; } + if (!POINTER_TYPE_P (type)) + return convert (type, TREE_OPERAND (expr, 0)); return TREE_OPERAND (expr, 0); case COMPONENT_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); if (base == error_mark_node) return base; @@ -6216,7 +6220,7 @@ fold_offsetof_1 (tree expr, enum tree_co break; case ARRAY_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); if (base == error_mark_node) return base; @@ -6273,23 +6277,16 @@ fold_offsetof_1 (tree expr, enum tree_co /* Handle static members of volatile structs. */ t = TREE_OPERAND (expr, 1); gcc_checking_assert (VAR_P (get_base_address (t))); - return fold_offsetof_1 (t); + return fold_offsetof (t, type); default: gcc_unreachable (); } + if (!POINTER_TYPE_P (type)) +return size_binop (PLUS_EXPR, base, convert (type, off)); return fold_build_pointer_plus (base, off); } - -/* Likewise, but convert it to the return type of offsetof. */ - -tree -fold_offsetof (tree expr) -{ - return convert (size_type_node, fold_offsetof_1 (expr)); -} - /* *PTYPE is an incomplete array. Complete it with a domain based on INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT --- gcc/c/c-fold.c.jj 2018-01-17 22:00:12.310228253 +0100 +++ gcc/c/c-fold.c 2018-05-09 10:30:04.185687645 +0200 @@ -473,7 +473,8 @@ c_fully_fold_internal (tree expr, bool i && (op1 = get_base_address (op0)) != NULL_TREE && INDIRECT_REF_P (op1) && TREE_CONSTANT (TREE_OPERA
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Tue, May 8, 2018 at 4:04 PM, Jakub Jelinek wrote: > On Tue, May 08, 2018 at 01:03:00PM -0400, Jason Merrill wrote: >> On Sun, May 6, 2018 at 1:56 PM, Jakub Jelinek wrote: >> > --- gcc/c-family/c-common.c.jj 2018-03-27 21:58:55.598502113 +0200 >> > +++ gcc/c-family/c-common.c 2018-05-05 10:55:47.951600802 +0200 >> > @@ -6171,7 +6171,7 @@ c_common_to_target_charset (HOST_WIDE_IN >> > traditional rendering of offsetof as a macro. Return the folded >> > result. */ >> > >> > tree >> > -fold_offsetof_1 (tree expr, enum tree_code ctx) >> > +fold_offsetof_1 (tree expr, bool nonptr, enum tree_code ctx) >> >> The comment needs to document the NONPTR parameter. > > Ok. > >> > @@ -6287,7 +6291,7 @@ fold_offsetof_1 (tree expr, enum tree_co >> > tree >> > fold_offsetof (tree expr) >> > { >> > - return convert (size_type_node, fold_offsetof_1 (expr)); >> > + return convert (size_type_node, fold_offsetof_1 (expr, true)); >> > } >> >> Since all the uses of fold_offset_1 involve converting to a particular >> type, I wonder about wrapping it so that the argument for nonptr is >> determined from that type. > > So like this? > > 2018-05-08 Jakub Jelinek > > PR c++/85662 > * c-common.h (fold_offsetof_1): Add TYPE argument. > * c-common.c (fold_offsetof_1): Add TYPE argument, if it is not a > pointer type, convert the pointer constant to TYPE and use size_binop > with PLUS_EXPR instead of fold_build_pointer_plus. Adjust recursive > calls. > (fold_offsetof): Pass size_type_node as TYPE to fold_offsetof_1. > > * c-fold.c (c_fully_fold_internal): Pass TREE_TYPE (expr) as TYPE > to fold_offsetof_1. > * c-typeck.c (build_unary_op): Pass argtype as TYPE to > fold_offsetof_1. > > * cp-gimplify.c (cp_fold): Pass TREE_TYPE (x) as TYPE to > fold_offsetof_1. > > * g++.dg/ext/offsetof2.C: New test. > > --- gcc/c-family/c-common.h.jj 2018-05-06 23:12:49.185619717 +0200 > +++ gcc/c-family/c-common.h 2018-05-08 21:47:40.976737821 +0200 > @@ -1033,7 +1033,7 @@ extern bool c_dump_tree (void *, tree); > > extern void verify_sequence_points (tree); > > -extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); > +extern tree fold_offsetof_1 (tree, tree, tree_code ctx = ERROR_MARK); > extern tree fold_offsetof (tree); > > extern int complete_array_type (tree *, tree, bool); > --- gcc/c-family/c-common.c.jj 2018-05-06 23:12:49.135619681 +0200 > +++ gcc/c-family/c-common.c 2018-05-08 21:56:24.635088315 +0200 > @@ -6168,10 +6168,12 @@ c_common_to_target_charset (HOST_WIDE_IN > > /* Fold an offsetof-like expression. EXPR is a nested sequence of component > references with an INDIRECT_REF of a constant at the bottom; much like the > - traditional rendering of offsetof as a macro. Return the folded result. > */ > + traditional rendering of offsetof as a macro. TYPE is the desired type of > + the whole expression to which it will be converted afterwards. > + Return the folded result. */ > > tree > -fold_offsetof_1 (tree expr, enum tree_code ctx) > +fold_offsetof_1 (tree type, tree expr, enum tree_code ctx) > { >tree base, off, t; >tree_code code = TREE_CODE (expr); > @@ -6196,10 +6198,12 @@ fold_offsetof_1 (tree expr, enum tree_co > error ("cannot apply % to a non constant address"); > return error_mark_node; > } > + if (!POINTER_TYPE_P (type)) > + return convert (type, TREE_OPERAND (expr, 0)); >return TREE_OPERAND (expr, 0); > > case COMPONENT_REF: > - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); > + base = fold_offsetof_1 (type, TREE_OPERAND (expr, 0), code); >if (base == error_mark_node) > return base; > > @@ -6216,7 +6220,7 @@ fold_offsetof_1 (tree expr, enum tree_co >break; > > case ARRAY_REF: > - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); > + base = fold_offsetof_1 (type, TREE_OPERAND (expr, 0), code); >if (base == error_mark_node) > return base; > > @@ -6273,12 +6277,14 @@ fold_offsetof_1 (tree expr, enum tree_co >/* Handle static members of volatile structs. */ >t = TREE_OPERAND (expr, 1); >gcc_checking_assert (VAR_P (get_base_address (t))); > - return fold_offsetof_1 (t); > + return fold_offsetof_1 (type, t); > > default: >gcc_unreachable (); > } > > + if (!POINTER_TYPE_P (type)) > +return size_binop (PLUS_EXPR, base, convert (type, off)); >return fold_build_pointer_plus (base, off); > } > > @@ -6287,7 +6293,7 @@ fold_offsetof_1 (tree expr, enum tree_co > tree > fold_offsetof (tree expr) > { > - return convert (size_type_node, fold_offsetof_1 (expr)); > + return convert (size_type_node, fold_offsetof_1 (size_type_node, expr)); > } Maybe add a type parameter that defaults to size_type_node... > > --- gcc/c/c-fold.c.jj 2018-01-17 22:00:12.310228253 +0100 > +++ gc
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Tue, May 08, 2018 at 01:03:00PM -0400, Jason Merrill wrote: > On Sun, May 6, 2018 at 1:56 PM, Jakub Jelinek wrote: > > --- gcc/c-family/c-common.c.jj 2018-03-27 21:58:55.598502113 +0200 > > +++ gcc/c-family/c-common.c 2018-05-05 10:55:47.951600802 +0200 > > @@ -6171,7 +6171,7 @@ c_common_to_target_charset (HOST_WIDE_IN > > traditional rendering of offsetof as a macro. Return the folded > > result. */ > > > > tree > > -fold_offsetof_1 (tree expr, enum tree_code ctx) > > +fold_offsetof_1 (tree expr, bool nonptr, enum tree_code ctx) > > The comment needs to document the NONPTR parameter. Ok. > > @@ -6287,7 +6291,7 @@ fold_offsetof_1 (tree expr, enum tree_co > > tree > > fold_offsetof (tree expr) > > { > > - return convert (size_type_node, fold_offsetof_1 (expr)); > > + return convert (size_type_node, fold_offsetof_1 (expr, true)); > > } > > Since all the uses of fold_offset_1 involve converting to a particular > type, I wonder about wrapping it so that the argument for nonptr is > determined from that type. So like this? 2018-05-08 Jakub Jelinek PR c++/85662 * c-common.h (fold_offsetof_1): Add TYPE argument. * c-common.c (fold_offsetof_1): Add TYPE argument, if it is not a pointer type, convert the pointer constant to TYPE and use size_binop with PLUS_EXPR instead of fold_build_pointer_plus. Adjust recursive calls. (fold_offsetof): Pass size_type_node as TYPE to fold_offsetof_1. * c-fold.c (c_fully_fold_internal): Pass TREE_TYPE (expr) as TYPE to fold_offsetof_1. * c-typeck.c (build_unary_op): Pass argtype as TYPE to fold_offsetof_1. * cp-gimplify.c (cp_fold): Pass TREE_TYPE (x) as TYPE to fold_offsetof_1. * g++.dg/ext/offsetof2.C: New test. --- gcc/c-family/c-common.h.jj 2018-05-06 23:12:49.185619717 +0200 +++ gcc/c-family/c-common.h 2018-05-08 21:47:40.976737821 +0200 @@ -1033,7 +1033,7 @@ extern bool c_dump_tree (void *, tree); extern void verify_sequence_points (tree); -extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); +extern tree fold_offsetof_1 (tree, tree, tree_code ctx = ERROR_MARK); extern tree fold_offsetof (tree); extern int complete_array_type (tree *, tree, bool); --- gcc/c-family/c-common.c.jj 2018-05-06 23:12:49.135619681 +0200 +++ gcc/c-family/c-common.c 2018-05-08 21:56:24.635088315 +0200 @@ -6168,10 +6168,12 @@ c_common_to_target_charset (HOST_WIDE_IN /* Fold an offsetof-like expression. EXPR is a nested sequence of component references with an INDIRECT_REF of a constant at the bottom; much like the - traditional rendering of offsetof as a macro. Return the folded result. */ + traditional rendering of offsetof as a macro. TYPE is the desired type of + the whole expression to which it will be converted afterwards. + Return the folded result. */ tree -fold_offsetof_1 (tree expr, enum tree_code ctx) +fold_offsetof_1 (tree type, tree expr, enum tree_code ctx) { tree base, off, t; tree_code code = TREE_CODE (expr); @@ -6196,10 +6198,12 @@ fold_offsetof_1 (tree expr, enum tree_co error ("cannot apply % to a non constant address"); return error_mark_node; } + if (!POINTER_TYPE_P (type)) + return convert (type, TREE_OPERAND (expr, 0)); return TREE_OPERAND (expr, 0); case COMPONENT_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof_1 (type, TREE_OPERAND (expr, 0), code); if (base == error_mark_node) return base; @@ -6216,7 +6220,7 @@ fold_offsetof_1 (tree expr, enum tree_co break; case ARRAY_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof_1 (type, TREE_OPERAND (expr, 0), code); if (base == error_mark_node) return base; @@ -6273,12 +6277,14 @@ fold_offsetof_1 (tree expr, enum tree_co /* Handle static members of volatile structs. */ t = TREE_OPERAND (expr, 1); gcc_checking_assert (VAR_P (get_base_address (t))); - return fold_offsetof_1 (t); + return fold_offsetof_1 (type, t); default: gcc_unreachable (); } + if (!POINTER_TYPE_P (type)) +return size_binop (PLUS_EXPR, base, convert (type, off)); return fold_build_pointer_plus (base, off); } @@ -6287,7 +6293,7 @@ fold_offsetof_1 (tree expr, enum tree_co tree fold_offsetof (tree expr) { - return convert (size_type_node, fold_offsetof_1 (expr)); + return convert (size_type_node, fold_offsetof_1 (size_type_node, expr)); } --- gcc/c/c-fold.c.jj 2018-01-17 22:00:12.310228253 +0100 +++ gcc/c/c-fold.c 2018-05-08 21:52:43.303940175 +0200 @@ -473,7 +473,8 @@ c_fully_fold_internal (tree expr, bool i && (op1 = get_base_address (op0)) != NULL_TREE && INDIRECT_REF_P (op1) && TREE_CONSTANT (TREE_OPERAND (op1, 0))) - ret = fold_convert_loc (loc, TREE_TYPE (expr),
Re: [C++ PATCH] Fix offsetof constexpr handling (PR c++/85662)
On Sun, May 6, 2018 at 1:56 PM, Jakub Jelinek wrote: > --- gcc/c-family/c-common.c.jj 2018-03-27 21:58:55.598502113 +0200 > +++ gcc/c-family/c-common.c 2018-05-05 10:55:47.951600802 +0200 > @@ -6171,7 +6171,7 @@ c_common_to_target_charset (HOST_WIDE_IN > traditional rendering of offsetof as a macro. Return the folded result. > */ > > tree > -fold_offsetof_1 (tree expr, enum tree_code ctx) > +fold_offsetof_1 (tree expr, bool nonptr, enum tree_code ctx) The comment needs to document the NONPTR parameter. > @@ -6287,7 +6291,7 @@ fold_offsetof_1 (tree expr, enum tree_co > tree > fold_offsetof (tree expr) > { > - return convert (size_type_node, fold_offsetof_1 (expr)); > + return convert (size_type_node, fold_offsetof_1 (expr, true)); > } Since all the uses of fold_offset_1 involve converting to a particular type, I wonder about wrapping it so that the argument for nonptr is determined from that type. Jason