In this test: struct S { enum { X }; };
int foo (struct S s) { return s.X; } unlike in C, lookup_member in C++ is able to find X in S. So in the following testcase finish_offsetof happily passes the CONST_DECL X down to fold_offsetof, which then crashes because fold_offsetof_1 doesn't handle CONST_DECLs. I think let's simply disallow 'em in finish_offsetof; we can't take their address anyway. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-03-23 Marek Polacek <pola...@redhat.com> PR c++/85033 * semantics.c (finish_offsetof): Don't allow CONST_DECLs. * g++.dg/ext/builtin-offsetof2.C: New test. diff --git gcc/cp/semantics.c gcc/cp/semantics.c index 97fa57ae94e..035e3951574 100644 --- gcc/cp/semantics.c +++ gcc/cp/semantics.c @@ -4072,6 +4072,11 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc) } return error_mark_node; } + if (TREE_CODE (expr) == CONST_DECL) + { + error ("cannot apply %<offsetof%> to an enumerator %qD", expr); + return error_mark_node; + } if (REFERENCE_REF_P (expr)) expr = TREE_OPERAND (expr, 0); if (!complete_type_or_else (TREE_TYPE (TREE_TYPE (object_ptr)), object_ptr)) diff --git gcc/testsuite/g++.dg/ext/builtin-offsetof2.C gcc/testsuite/g++.dg/ext/builtin-offsetof2.C index e69de29bb2d..07cc55a65c1 100644 --- gcc/testsuite/g++.dg/ext/builtin-offsetof2.C +++ gcc/testsuite/g++.dg/ext/builtin-offsetof2.C @@ -0,0 +1,7 @@ +// PR c++/85033 + +struct S { + enum { E }; +}; + +int b = __builtin_offsetof(S, E); // { dg-error "cannot apply .offsetof. to an enumerator" } Marek