From: Jason Merrill Date: Wed, 14 Apr 2021 13:30:05 +0000 (-0400) Subject: c++: non-static member, array bound, sizeof [PR93314] X-Git-Tag: basepoints/gcc-12~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b53edc796d284b6adec7f2996772dbddf4c341e;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 125772238d3c..4520181d4e59 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 000000000000..dfc1bb4e0c3e --- /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" } +}