aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-04-23 16:49:38 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-04-23 16:49:38 -0400
commitaa2b10551159df9eb1b33e049eb36ee53d379b4e (patch)
tree57df381f854d498e1870295c71d1c59e390e02d6 /gcc/cp
parent71fbbf65fa775dfe4a3fde9f20008389f9e0e53f (diff)
downloadgcc-aa2b10551159df9eb1b33e049eb36ee53d379b4e.zip
gcc-aa2b10551159df9eb1b33e049eb36ee53d379b4e.tar.gz
gcc-aa2b10551159df9eb1b33e049eb36ee53d379b4e.tar.bz2
PR c++/69560 - wrong alignof(double) on x86.
CWG 1879 - Inadequate definition of alignment requirement. * cp-tree.h (ALIGNOF_EXPR_STD_P): New. * typeck.c (cxx_sizeof_or_alignof_type): Add std_alignof parm. (cxx_sizeof_expr, cxx_sizeof_nowarn, cxx_alignas_expr) (cxx_alignof_expr): Pass it. * parser.c (cp_parser_unary_expression): Pass it. * pt.c (tsubst_copy): Copy it. (tsubst_copy_and_build): Pass it. * decl.c (fold_sizeof_expr): Pass it. From-SVN: r259578
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/cp/pt.c12
-rw-r--r--gcc/cp/typeck.c19
6 files changed, 48 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index aaed5d4..365592f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+2018-04-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/69560 - wrong alignof(double) on x86.
+ CWG 1879 - Inadequate definition of alignment requirement.
+ * cp-tree.h (ALIGNOF_EXPR_STD_P): New.
+ * typeck.c (cxx_sizeof_or_alignof_type): Add std_alignof parm.
+ (cxx_sizeof_expr, cxx_sizeof_nowarn, cxx_alignas_expr)
+ (cxx_alignof_expr): Pass it.
+ * parser.c (cp_parser_unary_expression): Pass it.
+ * pt.c (tsubst_copy): Copy it.
+ (tsubst_copy_and_build): Pass it.
+ * decl.c (fold_sizeof_expr): Pass it.
+
2018-04-23 Jakub Jelinek <jakub@redhat.com>
Jason Merrill <jason@redhat.com>
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5af4928..3777077 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -372,6 +372,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
TEMPLATE_TYPE_PARM_FOR_CLASS (TEMPLATE_TYPE_PARM)
DECL_NAMESPACE_INLINE_P (in NAMESPACE_DECL)
SWITCH_STMT_ALL_CASES_P (in SWITCH_STMT)
+ ALIGNOF_EXPR_STD_P (in ALIGNOF_EXPR)
1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -4954,6 +4955,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define SIZEOF_EXPR_TYPE_P(NODE) \
TREE_LANG_FLAG_0 (SIZEOF_EXPR_CHECK (NODE))
+/* True if the ALIGNOF_EXPR was spelled "alignof". */
+#define ALIGNOF_EXPR_STD_P(NODE) \
+ TREE_LANG_FLAG_0 (ALIGNOF_EXPR_CHECK (NODE))
+
/* An enumeration of the kind of tags that C++ accepts. */
enum tag_types {
none_type = 0, /* Not a tag type. */
@@ -7195,7 +7200,7 @@ extern int comp_cv_qualification (const_tree, const_tree);
extern int comp_cv_qualification (int, int);
extern int comp_cv_qual_signature (tree, tree);
extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool);
-extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
+extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool, bool);
extern tree cxx_alignas_expr (tree);
extern tree cxx_sizeof_nowarn (tree);
extern tree is_bitfield_expr_with_lowered_type (const_tree);
@@ -7292,7 +7297,7 @@ extern tree cp_build_binary_op (location_t,
extern tree build_x_vec_perm_expr (location_t,
tree, tree, tree,
tsubst_flags_t);
-#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
+#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false, true)
extern tree build_simple_component_ref (tree, tree);
extern tree build_ptrmemfunc_access_expr (tree, tree);
extern tree build_address (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d822745..55e2343 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9542,10 +9542,10 @@ fold_sizeof_expr (tree t)
tree r;
if (SIZEOF_EXPR_TYPE_P (t))
r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
- SIZEOF_EXPR, false);
+ SIZEOF_EXPR, false, false);
else if (TYPE_P (TREE_OPERAND (t, 0)))
r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
- false);
+ false, false);
else
r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
false);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bf46165f..d8ce28a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7993,19 +7993,22 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
location_t start_loc = token->location;
op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
+ bool std_alignof = id_equal (token->u.value, "alignof");
+
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
/* Parse the operand. */
operand = cp_parser_sizeof_operand (parser, keyword);
if (TYPE_P (operand))
- ret = cxx_sizeof_or_alignof_type (operand, op, true);
+ ret = cxx_sizeof_or_alignof_type (operand, op, std_alignof,
+ true);
else
{
/* ISO C++ defines alignof only with types, not with
expressions. So pedwarn if alignof is used with a non-
type expression. However, __alignof__ is ok. */
- if (id_equal (token->u.value, "alignof"))
+ if (std_alignof)
pedwarn (token->location, OPT_Wpedantic,
"ISO C++ does not allow %<alignof%> "
"with a non-type");
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e2a12b9..9fb8197 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15598,7 +15598,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
expanded = make_argument_pack (expanded);
if (TYPE_P (expanded))
- return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
+ return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
+ false,
complain & tf_error);
else
return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR,
@@ -15636,7 +15637,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
- return build1 (code, type, op0);
+ r = build1 (code, type, op0);
+ if (code == ALIGNOF_EXPR)
+ ALIGNOF_EXPR_STD_P (r) = ALIGNOF_EXPR_STD_P (t);
+ return r;
}
case COMPONENT_REF:
@@ -18002,6 +18006,8 @@ tsubst_copy_and_build (tree t,
op1 = TREE_OPERAND (t, 0);
if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
op1 = TREE_TYPE (op1);
+ bool std_alignof = (TREE_CODE (t) == ALIGNOF_EXPR
+ && ALIGNOF_EXPR_STD_P (t));
if (!args)
{
/* When there are no ARGS, we are trying to evaluate a
@@ -18025,7 +18031,7 @@ tsubst_copy_and_build (tree t,
--c_inhibit_evaluation_warnings;
}
if (TYPE_P (op1))
- r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
+ r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), std_alignof,
complain & tf_error);
else
r = cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t),
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index f5081c1..01baf6c 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1597,10 +1597,13 @@ compparms (const_tree parms1, const_tree parms2)
/* Process a sizeof or alignof expression where the operand is a
- type. */
+ type. STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
+ or GNU (preferred alignment) semantics; it is ignored if op is
+ SIZEOF_EXPR. */
tree
-cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
+cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool std_alignof,
+ bool complain)
{
tree value;
bool dependent_p;
@@ -1637,11 +1640,13 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
{
value = build_min (op, size_type_node, type);
TREE_READONLY (value) = 1;
+ if (op == ALIGNOF_EXPR && std_alignof)
+ ALIGNOF_EXPR_STD_P (value) = true;
return value;
}
return c_sizeof_or_alignof_type (input_location, complete_type (type),
- op == SIZEOF_EXPR, false,
+ op == SIZEOF_EXPR, std_alignof,
complain);
}
@@ -1659,7 +1664,7 @@ cxx_sizeof_nowarn (tree type)
else if (!COMPLETE_TYPE_P (type))
return size_zero_node;
else
- return cxx_sizeof_or_alignof_type (type, SIZEOF_EXPR, false);
+ return cxx_sizeof_or_alignof_type (type, SIZEOF_EXPR, false, false);
}
/* Process a sizeof expression where the operand is an expression. */
@@ -1725,7 +1730,7 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
else
e = TREE_TYPE (e);
- return cxx_sizeof_or_alignof_type (e, SIZEOF_EXPR, complain & tf_error);
+ return cxx_sizeof_or_alignof_type (e, SIZEOF_EXPR, false, complain & tf_error);
}
/* Implement the __alignof keyword: Return the minimum required
@@ -1786,7 +1791,7 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain)
t = size_one_node;
}
else
- return cxx_sizeof_or_alignof_type (TREE_TYPE (e), ALIGNOF_EXPR,
+ return cxx_sizeof_or_alignof_type (TREE_TYPE (e), ALIGNOF_EXPR, false,
complain & tf_error);
return fold_convert (size_type_node, t);
@@ -1825,7 +1830,7 @@ cxx_alignas_expr (tree e)
alignas(type-id ), it shall have the same effect as
alignas(alignof(type-id )). */
- return cxx_sizeof_or_alignof_type (e, ALIGNOF_EXPR, false);
+ return cxx_sizeof_or_alignof_type (e, ALIGNOF_EXPR, true, false);
/* If we reach this point, it means the alignas expression if of
the form "alignas(assignment-expression)", so we should follow