From e9f59cfa4a357121c65c0911de5ac0d271bcdc59 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 9 Apr 2018 16:40:06 -0400 Subject: [PATCH] PR c++/85277 - ICE with invalid offsetof. * semantics.c (finish_offsetof): Avoid passing non-DECL to %qD. Adjust -Winvalid-offsetof diagnostic to say conditionally supported. From-SVN: r259254 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/semantics.c | 22 ++++++++++---------- gcc/testsuite/g++.dg/ext/builtin-offsetof1.C | 6 ++++-- gcc/testsuite/g++.dg/other/offsetof3.C | 2 +- gcc/testsuite/g++.dg/other/offsetof5.C | 4 ++-- gcc/testsuite/g++.dg/other/offsetof8.C | 2 +- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f55a240186d..0017c34db75 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-04-09 Jason Merrill + PR c++/85277 - ICE with invalid offsetof. + * semantics.c (finish_offsetof): Avoid passing non-DECL to %qD. + Adjust -Winvalid-offsetof diagnostic to say conditionally supported. + PR c++/85264 - ICE with excess template-parameter-list. * parser.c (cp_parser_check_template_parameters): Add template_id_p parameter. Don't allow an extra template header if true. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 59cac77f6b7..8c893ed64b0 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4043,17 +4043,17 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc) || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE || TREE_TYPE (expr) == unknown_type_node) { - if (INDIRECT_REF_P (expr)) - error ("second operand of % is neither a single " - "identifier nor a sequence of member accesses and " - "array references"); - else + while (TREE_CODE (expr) == COMPONENT_REF + || TREE_CODE (expr) == COMPOUND_EXPR) + expr = TREE_OPERAND (expr, 1); + + if (DECL_P (expr)) { - if (TREE_CODE (expr) == COMPONENT_REF - || TREE_CODE (expr) == COMPOUND_EXPR) - expr = TREE_OPERAND (expr, 1); error ("cannot apply % to member function %qD", expr); + inform (DECL_SOURCE_LOCATION (expr), "declared here"); } + else + error ("cannot apply % to member function"); return error_mark_node; } if (TREE_CODE (expr) == CONST_DECL) @@ -4069,9 +4069,9 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc) && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr))) && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr))) && cp_unevaluated_operand == 0) - pedwarn (loc, OPT_Winvalid_offsetof, - "offsetof within non-standard-layout type %qT is undefined", - TREE_TYPE (TREE_TYPE (object_ptr))); + warning_at (loc, OPT_Winvalid_offsetof, "offsetof within " + "non-standard-layout type %qT is conditionally-supported", + TREE_TYPE (TREE_TYPE (object_ptr))); return fold_offsetof (expr); } diff --git a/gcc/testsuite/g++.dg/ext/builtin-offsetof1.C b/gcc/testsuite/g++.dg/ext/builtin-offsetof1.C index 5c5e9cf246b..cbc2daafbdd 100644 --- a/gcc/testsuite/g++.dg/ext/builtin-offsetof1.C +++ b/gcc/testsuite/g++.dg/ext/builtin-offsetof1.C @@ -1,9 +1,11 @@ // PR c++/51413 -// { dg-options "-w" } +// PR c++/85277 +// { dg-options "-Wno-pointer-arith" } struct A { static void foo(); }; -int i = __builtin_offsetof(A, foo[1]); // { dg-error "neither a single identifier nor a sequence of member accesses and array references" } +int i = __builtin_offsetof(A, foo[1]); // { dg-error "offsetof" } +int j = __builtin_offsetof(volatile A, foo[0]); // { dg-error "offsetof" } diff --git a/gcc/testsuite/g++.dg/other/offsetof3.C b/gcc/testsuite/g++.dg/other/offsetof3.C index 8d982426560..779fc72670a 100644 --- a/gcc/testsuite/g++.dg/other/offsetof3.C +++ b/gcc/testsuite/g++.dg/other/offsetof3.C @@ -12,4 +12,4 @@ protected: typedef X* pX; typedef __SIZE_TYPE__ size_t; -size_t yoff = __builtin_offsetof (X, y); /* { dg-error "35:non-standard-layout" } */ +size_t yoff = __builtin_offsetof (X, y); /* { dg-message "35:non-standard-layout" } */ diff --git a/gcc/testsuite/g++.dg/other/offsetof5.C b/gcc/testsuite/g++.dg/other/offsetof5.C index 86b14488246..8514af087ad 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-error "offsetof" } +int j = offsetof (A, i); // { dg-message "offsetof" } template struct S { T h; T &i; - static const int j = offsetof (S, i); // { dg-error "offsetof" } + static const int j = offsetof (S, i); // { dg-message "offsetof" } }; int k = S::j; // { dg-message "required from here" } diff --git a/gcc/testsuite/g++.dg/other/offsetof8.C b/gcc/testsuite/g++.dg/other/offsetof8.C index 0668199b366..211c5127026 100644 --- a/gcc/testsuite/g++.dg/other/offsetof8.C +++ b/gcc/testsuite/g++.dg/other/offsetof8.C @@ -9,4 +9,4 @@ struct B: virtual A { }; int a[] = { !&((B*)0)->i, // { dg-error "invalid access to non-static data member" } __builtin_offsetof (B, i) // { dg-error "invalid access to non-static" } -}; // { dg-error "offsetof within non-standard-layout type" "" { target *-*-* } .-1 } +}; // { dg-message "offsetof within non-standard-layout type" "" { target *-*-* } .-1 } -- 2.30.2