aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-14 09:30:05 -0400
committerJason Merrill <jason@redhat.com>2021-04-14 13:47:46 -0400
commit9b53edc796d284b6adec7f2996772dbddf4c341e (patch)
tree25e585b64c912f57d39957ed6368d4de3bf97b1d /gcc
parentf99f64f69db49ce6343d79a39eab28dcc6b91865 (diff)
downloadgcc-9b53edc796d284b6adec7f2996772dbddf4c341e.zip
gcc-9b53edc796d284b6adec7f2996772dbddf4c341e.tar.gz
gcc-9b53edc796d284b6adec7f2996772dbddf4c341e.tar.bz2
c++: non-static member, array bound, sizeof [PR93314]
N2253 allowed referring to non-static data members without an object in unevaluated operands like that of sizeof, but in a constant-expression context like an array bound or template argument within such an unevaluated operand we do actually need a value, so that permission cannot apply. gcc/cp/ChangeLog: PR c++/93314 * semantics.c (finish_id_expression_1): Clear cp_unevaluated_operand for a non-static data member in a constant-expression. gcc/testsuite/ChangeLog: PR c++/93314 * g++.dg/parse/uneval1.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/semantics.c10
-rw-r--r--gcc/testsuite/g++.dg/parse/uneval1.C14
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1257722..4520181 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4093,6 +4093,12 @@ finish_id_expression_1 (tree id_expression,
cp_warn_deprecated_use_scopes (scope);
+ /* In a constant-expression context, turn off cp_unevaluated_operand
+ so finish_non_static_data_member will complain (93314). */
+ auto eval = make_temp_override (cp_unevaluated_operand);
+ if (integral_constant_expression_p && TREE_CODE (decl) == FIELD_DECL)
+ cp_unevaluated_operand = 0;
+
if (TYPE_P (scope))
decl = finish_qualified_id_expr (scope,
decl,
@@ -4106,6 +4112,10 @@ finish_id_expression_1 (tree id_expression,
}
else if (TREE_CODE (decl) == FIELD_DECL)
{
+ auto eval = make_temp_override (cp_unevaluated_operand);
+ if (integral_constant_expression_p)
+ cp_unevaluated_operand = 0;
+
/* Since SCOPE is NULL here, this is an unqualified name.
Access checking has been performed during name lookup
already. Turn off checking to avoid duplicate errors. */
diff --git a/gcc/testsuite/g++.dg/parse/uneval1.C b/gcc/testsuite/g++.dg/parse/uneval1.C
new file mode 100644
index 0000000..dfc1bb4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/uneval1.C
@@ -0,0 +1,14 @@
+// PR c++/93314
+
+struct S {
+ int m;
+ static int f() {
+ return sizeof(char[m]); // { dg-error "S::m" }
+ }
+};
+
+int main()
+{
+ return S().f()
+ + sizeof(char[S::m]); // { dg-error "S::m" }
+}