public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-4925] c++: Correct the handling of alignof(expr) [PR88115]
@ 2020-11-11 20:11 Patrick Palka
0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2020-11-11 20:11 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:61827d5d9a5a09a8c05d5e41f95b03ebc6c43f61
commit r11-4925-g61827d5d9a5a09a8c05d5e41f95b03ebc6c43f61
Author: Patrick Palka <ppalka@redhat.com>
Date: Wed Nov 11 14:43:39 2020 -0500
c++: Correct the handling of alignof(expr) [PR88115]
We're currently neglecting to set the ALIGNOF_EXPR_STD_P flag on an
ALIGNOF_EXPR when its operand is an expression. This leads to us
handling alignof(expr) as if it were written __alignof__(expr), and
returning the preferred alignment instead of the ABI alignment. In the
testcase below, this causes the first and third static_assert to fail on
x86.
gcc/cp/ChangeLog:
PR c++/88115
* cp-tree.h (cxx_sizeof_or_alignof_expr): Add bool parameter.
* decl.c (fold_sizeof_expr): Pass false to
cxx_sizeof_or_alignof_expr.
* parser.c (cp_parser_unary_expression): Pass std_alignof to
cxx_sizeof_or_alignof_expr.
* pt.c (tsubst_copy): Pass false to cxx_sizeof_or_alignof_expr.
(tsubst_copy_and_build): Pass std_alignof to
cxx_sizeof_or_alignof_expr.
* typeck.c (cxx_alignof_expr): Add std_alignof bool parameter
and pass it to cxx_sizeof_or_alignof_type. Set ALIGNOF_EXPR_STD_P
appropriately.
(cxx_sizeof_or_alignof_expr): Add std_alignof bool parameter
and pass it to cxx_alignof_expr. Assert op is either
SIZEOF_EXPR or ALIGNOF_EXPR.
libcc1/ChangeLog:
PR c++/88115
* libcp1plugin.cc (plugin_build_unary_expr): Pass true to
cxx_sizeof_or_alignof_expr.
gcc/testsuite/ChangeLog:
PR c++/88115
* g++.dg/cpp0x/alignof6.C: New test.
Diff:
---
gcc/cp/cp-tree.h | 2 +-
gcc/cp/decl.c | 2 +-
gcc/cp/parser.c | 4 ++--
gcc/cp/pt.c | 3 ++-
gcc/cp/typeck.c | 17 +++++++++++------
gcc/testsuite/g++.dg/cpp0x/alignof6.C | 19 +++++++++++++++++++
libcc1/libcp1plugin.cc | 2 +-
7 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 230a1525c63..63724c0e84f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7461,7 +7461,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 (location_t, tree,
- enum tree_code, bool);
+ enum tree_code, bool, bool);
extern tree cxx_sizeof_or_alignof_type (location_t, tree,
enum tree_code, bool, bool);
extern tree cxx_alignas_expr (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 42e704e7af2..c52111e329c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10335,7 +10335,7 @@ fold_sizeof_expr (tree t)
else
r = cxx_sizeof_or_alignof_expr (EXPR_LOCATION (t),
TREE_OPERAND (t, 0), SIZEOF_EXPR,
- false);
+ false, false);
if (r == error_mark_node)
r = size_one_node;
return r;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 36322812310..4f59fc48d0f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8335,8 +8335,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
"ISO C++ does not allow %<alignof%> "
"with a non-type");
- ret = cxx_sizeof_or_alignof_expr (compound_loc,
- operand, op, true);
+ ret = cxx_sizeof_or_alignof_expr (compound_loc, operand, op,
+ std_alignof, true);
}
/* For SIZEOF_EXPR, just issue diagnostics, but keep
SIZEOF_EXPR with the original operand. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c592461c474..a932c2133e1 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16790,6 +16790,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
return cxx_sizeof_or_alignof_expr (input_location,
expanded, SIZEOF_EXPR,
+ false,
complain & tf_error);
}
else
@@ -19732,7 +19733,7 @@ tsubst_copy_and_build (tree t,
complain & tf_error);
else
r = cxx_sizeof_or_alignof_expr (input_location,
- op1, TREE_CODE (t),
+ op1, TREE_CODE (t), std_alignof,
complain & tf_error);
if (TREE_CODE (t) == SIZEOF_EXPR && r != error_mark_node)
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 08e0c80f9b0..700e166ca66 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1832,10 +1832,12 @@ cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
/* Implement the __alignof keyword: Return the minimum required
alignment of E, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
- "aligned" __attribute__ specification). */
+ "aligned" __attribute__ specification). STD_ALIGNOF acts
+ like in cxx_sizeof_or_alignof_type. */
static tree
-cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain)
+cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
+ tsubst_flags_t complain)
{
tree t;
@@ -1848,6 +1850,7 @@ cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain)
TREE_SIDE_EFFECTS (e) = 0;
TREE_READONLY (e) = 1;
SET_EXPR_LOCATION (e, loc);
+ ALIGNOF_EXPR_STD_P (e) = std_alignof;
return e;
}
@@ -1900,23 +1903,25 @@ cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain)
}
else
return cxx_sizeof_or_alignof_type (loc, TREE_TYPE (e),
- ALIGNOF_EXPR, false,
+ ALIGNOF_EXPR, std_alignof,
complain & tf_error);
return fold_convert_loc (loc, size_type_node, t);
}
/* Process a sizeof or alignof expression E with code OP where the operand
- is an expression. */
+ is an expression. STD_ALIGNOF acts like in cxx_sizeof_or_alignof_type. */
tree
cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
- bool complain)
+ bool std_alignof, bool complain)
{
+ gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
if (op == SIZEOF_EXPR)
return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
else
- return cxx_alignof_expr (loc, e, complain? tf_warning_or_error : tf_none);
+ return cxx_alignof_expr (loc, e, std_alignof,
+ complain? tf_warning_or_error : tf_none);
}
/* Build a representation of an expression 'alignas(E).' Return the
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignof6.C b/gcc/testsuite/g++.dg/cpp0x/alignof6.C
new file mode 100644
index 00000000000..b1a463df030
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignof6.C
@@ -0,0 +1,19 @@
+// PR c++/88115
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-pedantic" }
+
+// Verify the non-standard extension alignof(expr) behaves like
+// alignof(type) to yield the ABI alignment of the type, and that
+// __alignof__(expr) behaves like __alignof__(type) to yield the
+// preferred alignment of the type.
+
+static_assert(alignof(double{}) == alignof(double), "");
+static_assert(__alignof__(double{}) == __alignof__(double), "");
+
+template <class T>
+void f() {
+ static_assert(alignof(T{}) == alignof(T), "");
+ static_assert(__alignof__(T{}) == __alignof__(T), "");
+}
+
+template void f<double>();
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 67a235f9095..648368353cb 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -2806,7 +2806,7 @@ plugin_build_unary_expr (cc1_plugin::connection *self,
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
result = cxx_sizeof_or_alignof_expr (input_location,
- op0, opcode, true);
+ op0, opcode, true, true);
break;
case DELETE_EXPR:
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-11-11 20:11 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-11 20:11 [gcc r11-4925] c++: Correct the handling of alignof(expr) [PR88115] Patrick Palka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).