typeck.c (build_class_member_access_expr): Move -Winvalid-offsetof code...
authorJason Merrill <jason@redhat.com>
Tue, 9 Sep 2014 12:49:23 +0000 (08:49 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 9 Sep 2014 12:49:23 +0000 (08:49 -0400)
* 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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/doc/invoke.texi
gcc/testsuite/g++.dg/abi/offsetof.C
gcc/testsuite/g++.dg/other/offsetof3.C
gcc/testsuite/g++.dg/other/offsetof5.C

index 6447bc71795b16348b29c8c3f743d50791ab639e..ae54a68b73a47c219d0dca8d829601f6a48591f5 100644 (file)
@@ -1,5 +1,12 @@
 2014-09-08  Jason Merrill  <jason@redhat.com>
 
+       * 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.
index 43818cdcd0d8f85f915ae3146ea2ce0b5e3a5e9c..19f52329f25fd5d79ee9bb9af6c3cac0418e6993 100644 (file)
@@ -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);
index 05fa86a655b96ad0b3509a585349bc8de94798c5..c696fd2e6be3135bca3385f35011e3470f69ffb4 100644 (file)
@@ -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;
index 38093ecd67d501c1c8883b90b857166b3365e688..44569e23b1f6ccfc0c49b8aca04a9aedb6513900 100644 (file)
@@ -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:
       {
index 776fa264488a3e470e50d993aa81a7a85c1f5677..aee92ddc1d0adac69600d79fd05c94e9b7f314b6 100644 (file)
@@ -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);
 }
index 05fd48e372dc48035b358d7b1cd67f450e59aa72..aa82f1c0a78fc4726d02dc5079d2726de4e0d7f6 100644 (file)
@@ -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 %<offsetof%> 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 %<offsetof%> 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
index 56fc541dd682773d55ae78b6b06c8b659e6a2e06..ca9522a6016e945fd256922af025301e942c824c 100644 (file)
@@ -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.
 
index d6a53e6f80a283398867f69e3ab5834373bbd732..5a66511f2bdf7a7b844f65ea6efaed3550d062bd 100644 (file)
@@ -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*);
 }
index 5946c812ced7a983857c64c9a678fe7be8e7605d..8d98242656041bd72c4b379a035583cb0aa20a9d 100644 (file)
@@ -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 <austern@apple.com> 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" } */
index b53b06ffb52e8bc713c249fb3866c7bf5ebf975c..86b14488246131f370b2c9d7b4d9c6a4411d4966 100644 (file)
@@ -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 <typename T>
 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<int>::j;                     // { dg-message "required from here" }