aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.cc')
-rw-r--r--gcc/cp/class.cc54
1 files changed, 43 insertions, 11 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 2b694b9..6767ac1 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -6413,9 +6413,7 @@ check_bases_and_members (tree t)
Again, other conditions for being an aggregate are checked
elsewhere. */
CLASSTYPE_NON_AGGREGATE (t)
- |= ((cxx_dialect < cxx20
- ? type_has_user_provided_or_explicit_constructor (t)
- : TYPE_HAS_USER_CONSTRUCTOR (t))
+ |= (type_has_user_provided_or_explicit_constructor (t)
|| TYPE_POLYMORPHIC_P (t));
/* This is the C++98/03 definition of POD; it changed in C++0x, but we
retain the old definition internally for ABI reasons. */
@@ -6437,6 +6435,20 @@ check_bases_and_members (tree t)
CLASSTYPE_NON_LAYOUT_POD_P (t) = true;
}
+ /* P1008: Prohibit aggregates with user-declared constructors. */
+ if (cxx_dialect >= cxx20 && TYPE_HAS_USER_CONSTRUCTOR (t))
+ {
+ CLASSTYPE_NON_AGGREGATE (t) = true;
+ if (!CLASSTYPE_NON_LAYOUT_POD_P (t))
+ {
+ /* c++/120012: The C++20 aggregate change affected layout. */
+ if (!abi_version_at_least (21))
+ CLASSTYPE_NON_LAYOUT_POD_P (t) = true;
+ if (abi_version_crosses (21))
+ CLASSTYPE_NON_AGGREGATE_POD (t) = true;
+ }
+ }
+
/* If the only explicitly declared default constructor is user-provided,
set TYPE_HAS_COMPLEX_DFLT. */
if (!TYPE_HAS_COMPLEX_DFLT (t)
@@ -6809,7 +6821,8 @@ end_of_class (tree t, eoc_mode mode)
static void
check_non_pod_aggregate (tree field)
{
- if (!abi_version_crosses (17) || cxx_dialect < cxx14)
+ if ((!abi_version_crosses (17) || cxx_dialect < cxx14)
+ && (!abi_version_crosses (21) || cxx_dialect < cxx20))
return;
if (TREE_CODE (field) != FIELD_DECL
|| (!DECL_FIELD_IS_BASE (field)
@@ -6822,7 +6835,8 @@ check_non_pod_aggregate (tree field)
tree type = TREE_TYPE (field);
if (TYPE_IDENTIFIER (type) == as_base_identifier)
type = TYPE_CONTEXT (type);
- if (!CLASS_TYPE_P (type) || !CLASSTYPE_NON_POD_AGGREGATE (type))
+ if (!CLASS_TYPE_P (type) || (!CLASSTYPE_NON_POD_AGGREGATE (type)
+ && !CLASSTYPE_NON_AGGREGATE_POD (type)))
return;
tree size = end_of_class (type, (DECL_FIELD_IS_BASE (field)
? eoc_nvsize : eoc_nv_or_dsize));
@@ -6831,13 +6845,31 @@ check_non_pod_aggregate (tree field)
{
location_t loc = DECL_SOURCE_LOCATION (next);
if (DECL_FIELD_IS_BASE (next))
- warning_at (loc, OPT_Wabi,"offset of %qT base class for "
- "%<-std=c++14%> and up changes in "
- "%<-fabi-version=17%> (GCC 12)", TREE_TYPE (next));
+ {
+ if (abi_version_crosses (17)
+ && CLASSTYPE_NON_POD_AGGREGATE (type))
+ warning_at (loc, OPT_Wabi,"offset of %qT base class for "
+ "%<-std=c++14%> and up changes in "
+ "%<-fabi-version=17%> (GCC 12)", TREE_TYPE (next));
+ else if (abi_version_crosses (21)
+ && CLASSTYPE_NON_AGGREGATE_POD (type))
+ warning_at (loc, OPT_Wabi,"offset of %qT base class for "
+ "%<-std=c++20%> and up changes in "
+ "%<-fabi-version=21%> (GCC 16)", TREE_TYPE (next));
+ }
else
- warning_at (loc, OPT_Wabi, "offset of %qD for "
- "%<-std=c++14%> and up changes in "
- "%<-fabi-version=17%> (GCC 12)", next);
+ {
+ if (abi_version_crosses (17)
+ && CLASSTYPE_NON_POD_AGGREGATE (type))
+ warning_at (loc, OPT_Wabi, "offset of %qD for "
+ "%<-std=c++14%> and up changes in "
+ "%<-fabi-version=17%> (GCC 12)", next);
+ else if (abi_version_crosses (21)
+ && CLASSTYPE_NON_AGGREGATE_POD (type))
+ warning_at (loc, OPT_Wabi, "offset of %qD for "
+ "%<-std=c++20%> and up changes in "
+ "%<-fabi-version=21%> (GCC 16)", next);
+ }
}
}