https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123726
Boris Staletic <boris.staletic at protonmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |boris.staletic at protonmail
dot c
| |om
--- Comment #3 from Boris Staletic <boris.staletic at protonmail dot com> ---
(In reply to Jakub Jelinek from comment #2)
> This test is ICE on invalid, ^^m is a reflection of the m variable (with
> const int type), so obviously it can't be used for member access, so should
> be rejected.
>
> struct A { int a; } b;
>
> int
> main ()
> {
> b.[: ^^b :] = 5;
> }
>
> ICEs the same way.
> b.[: ^^:: :] = 5; is correctly rejected, so is b.[: ^^int :] = 5;
That makes the ICE quite clear.
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/cp/typeck.cc;h=20ef2a4d6df5550d1f5e22dcc6289c4541239f3c;hb=HEAD#l3599
The `[: ^^b :]` ends up as `name` whose code is VAR_DECL, so `VAR_P(name)` is
true.
Thus `scope` gets initialized and then gcc assumes that the `scope` must be a
class type.
That assumption holds for static member variables, but not for local variables.
Here's a patch that was tested on just the reduced test case:
```
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 20ef2a4d6d..ca37c3ece4 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3600,7 +3600,15 @@ finish_class_member_access_expr (cp_expr object, tree
name, bool template_p,
|| TREE_CODE (name) == CONST_DECL
|| TREE_CODE (name) == FUNCTION_DECL
|| DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))))
- scope = DECL_CONTEXT (OVL_FIRST (name));
+ {
+ scope = DECL_CONTEXT (OVL_FIRST (name));
+ if (VAR_P (name) && !CLASS_TYPE_P (scope))
+ {
+ if (complain & tf_error)
+ error ("%qD is not a class member", name);
+ return error_mark_node;
+ }
+ }
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
```
The produced error isn't perfect, but I'm very unfamiliar with the error
formatting API.
```
foo.cpp: In function ‘int main()’:
foo.cpp:4:12: error: ‘b’ is not a class member
4 | b.[: ^^b :];
| ^~
```