aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-05-10 19:40:28 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2018-05-10 19:40:28 +0200
commit79e7b1fe3290f351f178dafee4b3df4ece61ba9c (patch)
treed48f413c93e9cc59329413239736490ef5c5f916
parentc7b7749d9f2c68ca4f9cda52b21ef690aef009bd (diff)
downloadgcc-79e7b1fe3290f351f178dafee4b3df4ece61ba9c.zip
gcc-79e7b1fe3290f351f178dafee4b3df4ece61ba9c.tar.gz
gcc-79e7b1fe3290f351f178dafee4b3df4ece61ba9c.tar.bz2
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
-rw-r--r--gcc/c-family/ChangeLog12
-rw-r--r--gcc/c-family/c-common.c24
-rw-r--r--gcc/c-family/c-common.h4
-rw-r--r--gcc/c/ChangeLog10
-rw-r--r--gcc/c/c-fold.c2
-rw-r--r--gcc/c/c-typeck.c2
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-gimplify.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/offsetof2.C6
10 files changed, 54 insertions, 20 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 6ea5eaf..052b222 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,15 @@
+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>
PR c++/85400
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7e6905e..e8bb3eb 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.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
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_code ctx)
error ("cannot apply %<offsetof%> 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_code ctx)
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_code ctx)
/* 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
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 6cf7614..f2c6662 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index d88d70d..a8e2128 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,13 @@
+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>
PR c/30552
diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c
index 480e34c..d276e63 100644
--- a/gcc/c/c-fold.c
+++ b/gcc/c/c-fold.c
@@ -473,7 +473,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
&& (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_offsetof (op0, TREE_TYPE (expr));
else if (op0 != orig_op0 || in_init)
ret = in_init
? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 5b3ea28..45a4529 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -4676,7 +4676,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
if (val && INDIRECT_REF_P (val)
&& 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;
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a2de8f6..e21afc7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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>
PR c++/85400
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 7449065..84882f8 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -2232,7 +2232,7 @@ cp_fold (tree x)
val = TREE_OPERAND (val, 0);
STRIP_NOPS (val);
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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 694857b..89f6440 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
PR fortran/68846
diff --git a/gcc/testsuite/g++.dg/ext/offsetof2.C b/gcc/testsuite/g++.dg/ext/offsetof2.C
new file mode 100644
index 0000000..647cf8d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/offsetof2.C
@@ -0,0 +1,6 @@
+// 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]), "");