diff --git a/src/pending_changes/edg-28967-deep-pointer-qualification.txt b/src/pending_changes/edg-28967-deep-pointer-qualification.txt new file mode 100644 index 0000000000..f497b1ab30 --- /dev/null +++ b/src/pending_changes/edg-28967-deep-pointer-qualification.txt @@ -0,0 +1,5 @@ +[GH #455] +Reject unsafe deep pointer qualification conversions + +GNU C++ mode now rejects pointer qualification conversions that add const +at a deeper level without adding const at the required intermediate levels. diff --git a/src/types.c b/src/types.c index 3e8a3aed1b..4384a9ca85 100644 --- a/src/types.c +++ b/src/types.c @@ -11689,6 +11689,7 @@ operators), 3.3.15 (?: operator), and 3.3.16.1 (simple assignment). std_conv->warning_suggested = warning_suggested; qualifiers_checked = TRUE; } else if ((!suppress_extensions || any_cfront_mode()) && + !gpp_mode && same_type_with_added_qualifiers( source_type_pointed_to, dest_type_pointed_to, diff --git a/tests/tests/regressions/edg-28967-positive.sft.cpp b/tests/tests/regressions/edg-28967-positive.sft.cpp new file mode 100644 index 0000000000..1b29beb7ff --- /dev/null +++ b/tests/tests/regressions/edg-28967-positive.sft.cpp @@ -0,0 +1,9 @@ +//type:fp +//options_all:--c++20 +//options:--g++ --gnu_version=130300:--strict +void allow(char **p, char ***q) { + char *const *a = p; + const char *const *b = p; + const char *const *const *c = q; + (void)a; (void)b; (void)c; +} diff --git a/tests/tests/regressions/edg-28967.sft.cpp b/tests/tests/regressions/edg-28967.sft.cpp new file mode 100644 index 0000000000..a0b2c939c2 --- /dev/null +++ b/tests/tests/regressions/edg-28967.sft.cpp @@ -0,0 +1,9 @@ +//type:fn +//options_all:--c++20 +//options:--g++ --gnu_version=130300:--g++ --gnu_version=150200:--strict +void reject(char **p, char ***q) { + const char **bad = p; + const char ***also_bad = q; + (void)bad; + (void)also_bad; +}