This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/85277, ICE with invalid offsetof
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 9 Apr 2018 16:21:38 -0400
- Subject: C++ PATCH for c++/85277, ICE with invalid offsetof
Here, the code was improperly assuming that the member argument must
be a decl at the point of the error, but since we stopped folding
foo[0] to foo, in this case it's an INDIRECT_REF.
And the existing error for INDIRECT_REF is inaccurate for this case,
so let's stick to complaining about asking for offsetof a function.
While I was here, I updated the non-standard-layout diagnostic to say
"conditionally-supported" rather than undefined.
Tested x86_64-cp-linux-gnu, applying to trunk.
commit cb3221a892dc8ea6c06d148b3756d82067644869
Author: Jason Merrill <jason@redhat.com>
Date: Mon Apr 9 12:51:38 2018 -0400
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.
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 %<offsetof%> 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 %<offsetof%> to member function %qD", expr);
+ inform (DECL_SOURCE_LOCATION (expr), "declared here");
}
+ else
+ error ("cannot apply %<offsetof%> 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 <typename T>
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<int>::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 }