Commit 79e7b1fe by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/85662 ("error: non-constant condition for static assertion" from…

re PR c++/85662 ("error: non-constant condition for static assertion" from __builtin_offsetof in C++)

	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.

From-SVN: r260119
parent c7b7749d
2018-05-10 Jakub Jelinek <jakub@redhat.com>
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.
2018-05-10 Eric Botcazou <ebotcazou@adacore.com> 2018-05-10 Eric Botcazou <ebotcazou@adacore.com>
PR c++/85400 PR c++/85400
......
...@@ -6168,10 +6168,11 @@ c_common_to_target_charset (HOST_WIDE_INT c) ...@@ -6168,10 +6168,11 @@ c_common_to_target_charset (HOST_WIDE_INT c)
/* Fold an offsetof-like expression. EXPR is a nested sequence of component /* 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 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 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 base, off, t;
tree_code code = TREE_CODE (expr); tree_code code = TREE_CODE (expr);
...@@ -6196,10 +6197,10 @@ fold_offsetof_1 (tree expr, enum tree_code ctx) ...@@ -6196,10 +6197,10 @@ fold_offsetof_1 (tree expr, enum tree_code ctx)
error ("cannot apply %<offsetof%> to a non constant address"); error ("cannot apply %<offsetof%> to a non constant address");
return error_mark_node; return error_mark_node;
} }
return TREE_OPERAND (expr, 0); return convert (type, TREE_OPERAND (expr, 0));
case COMPONENT_REF: 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) if (base == error_mark_node)
return base; return base;
...@@ -6216,7 +6217,7 @@ fold_offsetof_1 (tree expr, enum tree_code ctx) ...@@ -6216,7 +6217,7 @@ fold_offsetof_1 (tree expr, enum tree_code ctx)
break; break;
case ARRAY_REF: 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) if (base == error_mark_node)
return base; return base;
...@@ -6273,23 +6274,16 @@ fold_offsetof_1 (tree expr, enum tree_code ctx) ...@@ -6273,23 +6274,16 @@ fold_offsetof_1 (tree expr, enum tree_code ctx)
/* Handle static members of volatile structs. */ /* Handle static members of volatile structs. */
t = TREE_OPERAND (expr, 1); t = TREE_OPERAND (expr, 1);
gcc_checking_assert (VAR_P (get_base_address (t))); gcc_checking_assert (VAR_P (get_base_address (t)));
return fold_offsetof_1 (t); return fold_offsetof (t, type);
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
if (!POINTER_TYPE_P (type))
return size_binop (PLUS_EXPR, base, convert (type, off));
return fold_build_pointer_plus (base, 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 /* *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 INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT
......
...@@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree); ...@@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree);
extern void verify_sequence_points (tree); extern void verify_sequence_points (tree);
extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); extern tree fold_offsetof (tree, tree = size_type_node,
extern tree fold_offsetof (tree); tree_code ctx = ERROR_MARK);
extern int complete_array_type (tree *, tree, bool); extern int complete_array_type (tree *, tree, bool);
......
2018-05-10 Jakub Jelinek <jakub@redhat.com>
PR c++/85662
* 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.
2018-05-02 David Pagan <dave.pagan@oracle.com> 2018-05-02 David Pagan <dave.pagan@oracle.com>
PR c/30552 PR c/30552
......
...@@ -473,7 +473,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, ...@@ -473,7 +473,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
&& (op1 = get_base_address (op0)) != NULL_TREE && (op1 = get_base_address (op0)) != NULL_TREE
&& INDIRECT_REF_P (op1) && INDIRECT_REF_P (op1)
&& TREE_CONSTANT (TREE_OPERAND (op1, 0))) && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); ret = fold_offsetof (op0, TREE_TYPE (expr));
else if (op0 != orig_op0 || in_init) else if (op0 != orig_op0 || in_init)
ret = in_init ret = in_init
? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
......
...@@ -4676,7 +4676,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, ...@@ -4676,7 +4676,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
if (val && INDIRECT_REF_P (val) if (val && INDIRECT_REF_P (val)
&& TREE_CONSTANT (TREE_OPERAND (val, 0))) && TREE_CONSTANT (TREE_OPERAND (val, 0)))
{ {
ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg)); ret = fold_offsetof (arg, argtype);
goto return_build_unary_op; goto return_build_unary_op;
} }
......
2018-05-10 Jakub Jelinek <jakub@redhat.com>
PR c++/85662
* 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.
2018-05-10 Eric Botcazou <ebotcazou@adacore.com> 2018-05-10 Eric Botcazou <ebotcazou@adacore.com>
PR c++/85400 PR c++/85400
......
...@@ -2232,7 +2232,7 @@ cp_fold (tree x) ...@@ -2232,7 +2232,7 @@ cp_fold (tree x)
val = TREE_OPERAND (val, 0); val = TREE_OPERAND (val, 0);
STRIP_NOPS (val); STRIP_NOPS (val);
if (TREE_CODE (val) == INTEGER_CST) if (TREE_CODE (val) == INTEGER_CST)
return fold_convert (TREE_TYPE (x), fold_offsetof_1 (op0)); return fold_offsetof (op0, TREE_TYPE (x));
} }
} }
goto finish_unary; goto finish_unary;
......
2018-05-10 Jakub Jelinek <jakub@redhat.com>
PR c++/85662
* g++.dg/ext/offsetof2.C: New test.
2018-05-10 Paul Thomas <pault@gcc.gnu.org> 2018-05-10 Paul Thomas <pault@gcc.gnu.org>
PR fortran/68846 PR fortran/68846
......
// PR c++/85662
// { dg-do compile { target c++11 } }
struct S { unsigned long x[31]; };
struct T { bool b; S f; };
static_assert (__builtin_offsetof (T, f.x[31 - 1]) == __builtin_offsetof (T, f.x[30]), "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment