From: Jason Merrill Date: Tue, 9 Sep 2014 12:49:23 +0000 (-0400) Subject: typeck.c (build_class_member_access_expr): Move -Winvalid-offsetof code... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8591575ff8d7959e829fd13eb171aefe2a60bc19;p=gcc.git typeck.c (build_class_member_access_expr): Move -Winvalid-offsetof code... * typeck.c (build_class_member_access_expr): Move -Winvalid-offsetof code... * semantics.c (finish_offsetof): ...here. * parser.c (cp_parser_builtin_offsetof): Remember the location of the type argument. * pt.c (tsubst_copy_and_build) [OFFSETOF_EXPR]: Preserve it. From-SVN: r215070 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6447bc71795..ae54a68b73a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2014-09-08 Jason Merrill + * typeck.c (build_class_member_access_expr): Move + -Winvalid-offsetof code... + * semantics.c (finish_offsetof): ...here. + * parser.c (cp_parser_builtin_offsetof): Remember the location of + the type argument. + * pt.c (tsubst_copy_and_build) [OFFSETOF_EXPR]: Preserve it. + PR c++/62255 * pt.c (instantiate_decl): Handle recursive instantiation of static data member. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 43818cdcd0d..19f52329f25 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5879,7 +5879,7 @@ extern tree finish_underlying_type (tree); extern tree calculate_bases (tree); extern tree finish_bases (tree, bool); extern tree calculate_direct_bases (tree); -extern tree finish_offsetof (tree); +extern tree finish_offsetof (tree, location_t); extern void finish_decl_cleanup (tree, tree); extern void finish_eh_cleanup (tree); extern void emit_associated_thunks (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 05fa86a655b..c696fd2e6be 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8577,6 +8577,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) /* Consume the opening `('. */ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the type-id. */ + location_t loc = cp_lexer_peek_token (parser->lexer)->location; type = cp_parser_type_id (parser); /* Look for the `,'. */ cp_parser_require (parser, CPP_COMMA, RT_COMMA); @@ -8633,9 +8634,12 @@ cp_parser_builtin_offsetof (cp_parser *parser) /* If we're processing a template, we can't finish the semantics yet. Otherwise we can fold the entire expression now. */ if (processing_template_decl) - expr = build1 (OFFSETOF_EXPR, size_type_node, expr); + { + expr = build1 (OFFSETOF_EXPR, size_type_node, expr); + SET_EXPR_LOCATION (expr, loc); + } else - expr = finish_offsetof (expr); + expr = finish_offsetof (expr, loc); failure: parser->integral_constant_expression_p = save_ice_p; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 38093ecd67d..44569e23b1f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15440,7 +15440,8 @@ tsubst_copy_and_build (tree t, } case OFFSETOF_EXPR: - RETURN (finish_offsetof (RECUR (TREE_OPERAND (t, 0)))); + RETURN (finish_offsetof (RECUR (TREE_OPERAND (t, 0)), + EXPR_LOCATION (t))); case TRAIT_EXPR: { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 776fa264488..aee92ddc1d0 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3814,7 +3814,7 @@ finish_bases (tree type, bool direct) fold_offsetof. */ tree -finish_offsetof (tree expr) +finish_offsetof (tree expr, location_t loc) { if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) { @@ -3846,6 +3846,13 @@ finish_offsetof (tree expr) tree object = TREE_OPERAND (expr, 0); if (!complete_type_or_else (TREE_TYPE (object), object)) return error_mark_node; + if (warn_invalid_offsetof + && CLASS_TYPE_P (TREE_TYPE (object)) + && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (object)) + && cp_unevaluated_operand == 0) + pedwarn (loc, OPT_Winvalid_offsetof, + "offsetof within non-standard-layout type %qT is undefined", + TREE_TYPE (object)); } return fold_offsetof (expr); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 05fd48e372d..aa82f1c0a78 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2359,10 +2359,8 @@ build_class_member_access_expr (tree object, tree member, { if (complain & tf_error) { - error ("invalid access to non-static data member %qD of " - "NULL object", - member); - error ("(perhaps the % macro was used incorrectly)"); + error ("invalid access to non-static data member %qD in " + "virtual base of NULL object", member); } return error_mark_node; } @@ -2375,27 +2373,6 @@ build_class_member_access_expr (tree object, tree member, gcc_assert (object != error_mark_node); } - /* Complain about other invalid uses of offsetof, even though they will - give the right answer. Note that we complain whether or not they - actually used the offsetof macro, since there's no way to know at this - point. So we just give a warning, instead of a pedwarn. */ - /* Do not produce this warning for base class field references, because - we know for a fact that didn't come from offsetof. This does occur - in various testsuite cases where a null object is passed where a - vtable access is required. */ - if (null_object_p && warn_invalid_offsetof - && CLASSTYPE_NON_STD_LAYOUT (object_type) - && !DECL_FIELD_IS_BASE (member) - && cp_unevaluated_operand == 0 - && (complain & tf_warning)) - { - warning (OPT_Winvalid_offsetof, - "invalid access to non-static data member %qD " - " of NULL object", member); - warning (OPT_Winvalid_offsetof, - "(perhaps the % macro was used incorrectly)"); - } - /* If MEMBER is from an anonymous aggregate, we have converted OBJECT so that it refers to the class containing the anonymous union. Generate a reference to the anonymous union diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 56fc541dd68..ca9522a6016 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -5098,12 +5098,10 @@ warnings produced by @option{-Winline} to appear or disappear. @opindex Wno-invalid-offsetof @opindex Winvalid-offsetof Suppress warnings from applying the @samp{offsetof} macro to a non-POD -type. According to the 1998 ISO C++ standard, applying @samp{offsetof} -to a non-POD type is undefined. In existing C++ implementations, -however, @samp{offsetof} typically gives meaningful results even when -applied to certain kinds of non-POD types (such as a simple -@samp{struct} that fails to be a POD type only by virtue of having a -constructor). This flag is for users who are aware that they are +type. According to the 2014 ISO C++ standard, applying @samp{offsetof} +to a non-standard-layout type is undefined. In existing C++ implementations, +however, @samp{offsetof} typically gives meaningful results. +This flag is for users who are aware that they are writing nonportable code and who have deliberately chosen to ignore the warning about it. diff --git a/gcc/testsuite/g++.dg/abi/offsetof.C b/gcc/testsuite/g++.dg/abi/offsetof.C index d6a53e6f80a..5a66511f2bd 100644 --- a/gcc/testsuite/g++.dg/abi/offsetof.C +++ b/gcc/testsuite/g++.dg/abi/offsetof.C @@ -4,7 +4,6 @@ // implementation thereof. // Yes, this is bad, naughty, evil code. But it seems to be well-formed. -// So we'll just warn. // { dg-do run } @@ -18,5 +17,5 @@ struct C: public B { }; int main () { - return ((__SIZE_TYPE__) &((C*)0)->i) != sizeof(void*); // { dg-warning "offsetof|invalid" "" } + return ((__SIZE_TYPE__) &((C*)0)->i) != sizeof(void*); } diff --git a/gcc/testsuite/g++.dg/other/offsetof3.C b/gcc/testsuite/g++.dg/other/offsetof3.C index 5946c812ced..8d982426560 100644 --- a/gcc/testsuite/g++.dg/other/offsetof3.C +++ b/gcc/testsuite/g++.dg/other/offsetof3.C @@ -1,7 +1,6 @@ -/* Verify that offsetof warns if given a non-standard-layout class */ +/* Verify that offsetof complains if given a non-standard-layout class. */ /* Copyright (C) 2003 Free Software Foundation, Inc. */ /* Contributed by Matt Austern 15 May 2003 */ -/* { dg-do compile } */ struct X { @@ -13,5 +12,4 @@ protected: typedef X* pX; typedef __SIZE_TYPE__ size_t; -size_t yoff = size_t(&(pX(0)->y)); /* { dg-warning "invalid access" "" } */ -/* { dg-warning "macro was used incorrectly" "macro" { target *-*-* } 16 } */ +size_t yoff = __builtin_offsetof (X, y); /* { dg-error "35:non-standard-layout" } */ diff --git a/gcc/testsuite/g++.dg/other/offsetof5.C b/gcc/testsuite/g++.dg/other/offsetof5.C index b53b06ffb52..86b14488246 100644 --- a/gcc/testsuite/g++.dg/other/offsetof5.C +++ b/gcc/testsuite/g++.dg/other/offsetof5.C @@ -9,14 +9,14 @@ struct A int &i; }; -int j = offsetof (A, i); // { dg-warning "invalid access|offsetof" } +int j = offsetof (A, i); // { dg-error "offsetof" } template struct S { T h; T &i; - static const int j = offsetof (S, i); // { dg-warning "invalid access|offsetof" } + static const int j = offsetof (S, i); // { dg-error "offsetof" } }; int k = S::j; // { dg-message "required from here" }