aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-09-09 08:49:23 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-09-09 08:49:23 -0400
commit8591575ff8d7959e829fd13eb171aefe2a60bc19 (patch)
treeeec8d8211d7808205af1ac2ac89e273765de0a03 /gcc
parent97f518b3fe714bb026f8070aa475e86ddbcca509 (diff)
downloadgcc-8591575ff8d7959e829fd13eb171aefe2a60bc19.zip
gcc-8591575ff8d7959e829fd13eb171aefe2a60bc19.tar.gz
gcc-8591575ff8d7959e829fd13eb171aefe2a60bc19.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/parser.c8
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/cp/semantics.c9
-rw-r--r--gcc/cp/typeck.c27
-rw-r--r--gcc/doc/invoke.texi10
-rw-r--r--gcc/testsuite/g++.dg/abi/offsetof.C3
-rw-r--r--gcc/testsuite/g++.dg/other/offsetof3.C6
-rw-r--r--gcc/testsuite/g++.dg/other/offsetof5.C4
10 files changed, 35 insertions, 44 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6447bc7..ae54a68 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 43818cd..19f5232 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 05fa86a..c696fd2 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 38093ec..44569e23 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 776fa26..aee92dd 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 05fd48e..aa82f1c 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 %<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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 56fc541..ca9522a 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 d6a53e6..5a66511 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 5946c81..8d98242 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 <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" } */
diff --git a/gcc/testsuite/g++.dg/other/offsetof5.C b/gcc/testsuite/g++.dg/other/offsetof5.C
index b53b06f..86b1448 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 <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" }