Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/pending_changes/edg-28967-deep-pointer-qualification.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[GH #455]
GNU/Clang compatibility: unsafe multilevel pointer qualification conversions

In GNU and Clang C++ modes, an implicit conversion between multilevel pointer
types that adds const below the first level without adding it at every
intermediate level (e.g., "char **" to "const char **") was accepted with a
warning. Such a conversion is not const-safe and is not a valid qualification
conversion; GCC and Clang reject it. It is now an error. The qualification
conversion changes for EDGcpfe/18553 are now also enabled for Clang 7.x and
later, and the version check for MSVC 19.14 and later has been corrected.
Conversions to arrays of unknown bound remain disabled for Clang versions
before 14. For example, with --g++:

void f(char **p) {
const char **q = p; // Now an error.
}
21 changes: 13 additions & 8 deletions src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -10989,16 +10989,17 @@ weird Microsoft-mode handling of the __unaligned and __restrict qualifiers).
} /* if */
dest_type = pm_member_type(dest_type);
source_type = pm_member_type(source_type);
} else if (!gpp_version_is(<80000) && !clang_mode &&
!ms_version_is(>= 1914) &&
} else if (!gpp_version_is(<80000) && !clang_version_is(<70000) &&
!ms_version_is(<1914) &&
is_array(source_type) && is_array(dest_type)) {
/* N4261 reworked qualification conversions to include arrays (thereby
resolving Core issue 330). GCC versions prior to 8.x, Clang, and
(some versions of) MSVC do not appear to implement that yet.
P0338R4 (in C++20) adjusted this further to allow conversions from
arrays with known bounds to arrays with unknown bounds. */
resolving Core issue 330). Older emulated compilers do not
implement that. P0388R4 (in C++20) adjusted this further to allow
conversions from arrays with known bounds to arrays with unknown
bounds. */
if (!identical_array_type_level(source_type, dest_type) &&
!(cpp20_mode && !has_unknown_specified_bound(dest_type) &&
!(cpp20_mode && !clang_version_is(<140000) &&
!has_unknown_specified_bound(dest_type) &&
dest_type->variant.array.variant.number_of_elements == 0)) {
same = FALSE;
break;
Expand Down Expand Up @@ -11384,6 +11385,7 @@ conversion in C++/CLI because it drops gc-ness of an interior_ptr.

#endif /* MICROSOFT_EXTENSIONS_ALLOWED */


a_boolean impl_pointer_conversion(
a_type_ptr source_type,
a_boolean source_is_constant,
Expand Down Expand Up @@ -11689,6 +11691,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,
Expand All @@ -11700,7 +11703,9 @@ operators), 3.3.15 (?: operator), and 3.3.16.1 (simple assignment).
"int **" -> "const int **". This is similar to the qualification
conversion that is checked above, except that a few additional
cases are accepted. These are cases that are not const-safe,
so a warning is issued in most modes. This is an extension. */
so a warning is issued in most modes. This is an extension,
which is not provided in GNU and Clang modes since GCC and Clang
reject such conversions. */
okay = TRUE;
std_conv->nontrivial_conversion = FALSE;
std_conv->type_qualifiers_added = qualifiers_added;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,14 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const auto **fail2(p); // expected-error {{variable 'fail2' with type 'const auto **' has incompatible initializer of type 'int **'}}
^

"Test_name.c", line 60: warning: a value of type "int **" cannot be used to initialize an entity of type "const int **"
"Test_name.c", line 60: error: a value of type "int **" cannot be used to initialize an entity of type "const int **"
const auto **fail2(p); // expected-error {{variable 'fail2' with type 'const auto **' has incompatible initializer of type 'int **'}}
^

"Test_name.c", line 60: warning: variable "p" is used before its value is set
const auto **fail2(p); // expected-error {{variable 'fail2' with type 'const auto **' has incompatible initializer of type 'int **'}}
^

"Test_name.c", line 60: warning: variable "fail2" was declared but never referenced
const auto **fail2(p); // expected-error {{variable 'fail2' with type 'const auto **' has incompatible initializer of type 'int **'}}
^

"Test_name.c", line 70: warning: "auto" as a type specifier is nonstandard in this mode
auto p1 = &S::f;
^
Expand Down Expand Up @@ -123,4 +119,4 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int (*funcptr2)(int) = funcptr;
^

4 errors detected in the compilation of "Test_name.c".
5 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -59,4 +55,4 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

10 errors detected in the compilation of "Test_name.c".
11 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -92,4 +88,4 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

14 errors detected in the compilation of "Test_name.c".
15 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ fe_only -DTEST_NUMBER=3 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -96,4 +92,4 @@ fe_only -DTEST_NUMBER=3 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

15 errors detected in the compilation of "Test_name.c".
16 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ fe_only -DTEST_NUMBER=4 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -102,4 +98,4 @@ fe_only -DTEST_NUMBER=4 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

17 errors detected in the compilation of "Test_name.c".
18 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ fe_only -DTEST_NUMBER=5 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -152,4 +148,4 @@ fe_only -DTEST_NUMBER=5 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

20 errors detected in the compilation of "Test_name.c".
21 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ fe_only -DTEST_NUMBER=6 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -152,4 +148,4 @@ fe_only -DTEST_NUMBER=6 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

20 errors detected in the compilation of "Test_name.c".
21 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ fe_only -DTEST_NUMBER=7 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
int *const *const &f2() { return p; }
^

"Test_name.c", line 261: warning: return value type does not match the function type
const int **const &f4() { return p; }
^

"Test_name.c", line 261: warning: returning reference to local temporary
"Test_name.c", line 261: error: return value type does not match the function type
const int **const &f4() { return p; }
^

Expand Down Expand Up @@ -152,4 +148,4 @@ fe_only -DTEST_NUMBER=7 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A a;
^

20 errors detected in the compilation of "Test_name.c".
21 errors detected in the compilation of "Test_name.c".
12 changes: 2 additions & 10 deletions tests/tests/imported/clang/cpp/CXX/drs/.cwg3xx.rto/default.1.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of class "cwg329::A<T> [with T=int]" at line 453

"Test_name.c", line 467: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q" (aka "const int *const (*)[3]")
q = p; // ok
^

"Test_name.c", line 468: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q2" (aka "const cwg330::Qinner *")
q2 = p; // ok
^

"Test_name.c", line 469: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::R" (aka "const int *const (*)[4]")
r = p;
^
Expand Down Expand Up @@ -789,7 +781,7 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of "void cwg345::f(T) [with T=cwg345::A]" at line 753

"Test_name.c", line 787: warning: return value type does not match the function type
"Test_name.c", line 787: error: return value type does not match the function type
return p;
^
detected during instantiation of "cwg349::A::operator T ***() [with T=const int]" at line 796
Expand Down Expand Up @@ -849,4 +841,4 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
const A b(a);
^

154 errors detected in the compilation of "Test_name.c".
155 errors detected in the compilation of "Test_name.c".
12 changes: 2 additions & 10 deletions tests/tests/imported/clang/cpp/CXX/drs/.cwg3xx.rto/default.2.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,6 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of class "cwg329::A<T> [with T=int]" at line 453

"Test_name.c", line 467: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q" (aka "const int *const (*)[3]")
q = p; // ok
^

"Test_name.c", line 468: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q2" (aka "const cwg330::Qinner *")
q2 = p; // ok
^

"Test_name.c", line 469: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::R" (aka "const int *const (*)[4]")
r = p;
^
Expand Down Expand Up @@ -751,7 +743,7 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of "void cwg345::f(T) [with T=cwg345::A]" at line 753

"Test_name.c", line 787: warning: return value type does not match the function type
"Test_name.c", line 787: error: return value type does not match the function type
return p;
^
detected during instantiation of "cwg349::A::operator T ***() [with T=const int]" at line 796
Expand Down Expand Up @@ -831,4 +823,4 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
extern WithoutLinkage5 withoutLinkage5;
^

155 errors detected in the compilation of "Test_name.c".
156 errors detected in the compilation of "Test_name.c".
12 changes: 2 additions & 10 deletions tests/tests/imported/clang/cpp/CXX/drs/.cwg3xx.rto/default.3.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,6 @@ fe_only -DTEST_NUMBER=3 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of class "cwg329::A<T> [with T=int]" at line 453

"Test_name.c", line 467: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q" (aka "const int *const (*)[3]")
q = p; // ok
^

"Test_name.c", line 468: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q2" (aka "const cwg330::Qinner *")
q2 = p; // ok
^

"Test_name.c", line 469: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::R" (aka "const int *const (*)[4]")
r = p;
^
Expand Down Expand Up @@ -743,7 +735,7 @@ fe_only -DTEST_NUMBER=3 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of "void cwg345::f(T) [with T=cwg345::A]" at line 753

"Test_name.c", line 787: warning: return value type does not match the function type
"Test_name.c", line 787: error: return value type does not match the function type
return p;
^
detected during instantiation of "cwg349::A::operator T ***() [with T=const int]" at line 796
Expand Down Expand Up @@ -823,4 +815,4 @@ fe_only -DTEST_NUMBER=3 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
extern WithoutLinkage5 withoutLinkage5;
^

155 errors detected in the compilation of "Test_name.c".
156 errors detected in the compilation of "Test_name.c".
12 changes: 2 additions & 10 deletions tests/tests/imported/clang/cpp/CXX/drs/.cwg3xx.rto/default.4.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,6 @@ fe_only -DTEST_NUMBER=4 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of class "cwg329::A<T> [with T=int]" at line 453

"Test_name.c", line 467: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q" (aka "const int *const (*)[3]")
q = p; // ok
^

"Test_name.c", line 468: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q2" (aka "const cwg330::Qinner *")
q2 = p; // ok
^

"Test_name.c", line 469: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::R" (aka "const int *const (*)[4]")
r = p;
^
Expand Down Expand Up @@ -739,7 +731,7 @@ fe_only -DTEST_NUMBER=4 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of "void cwg345::f(T) [with T=cwg345::A]" at line 753

"Test_name.c", line 787: warning: return value type does not match the function type
"Test_name.c", line 787: error: return value type does not match the function type
return p;
^
detected during instantiation of "cwg349::A::operator T ***() [with T=const int]" at line 796
Expand Down Expand Up @@ -819,4 +811,4 @@ fe_only -DTEST_NUMBER=4 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
extern WithoutLinkage5 withoutLinkage5;
^

155 errors detected in the compilation of "Test_name.c".
156 errors detected in the compilation of "Test_name.c".
Original file line number Diff line number Diff line change
Expand Up @@ -161,22 +161,10 @@ fe_only -DTEST_NUMBER=5 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of class "cwg329::A<T> [with T=int]" at line 453

"Test_name.c", line 467: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q" (aka "const int *const (*)[3]")
q = p; // ok
^

"Test_name.c", line 468: warning: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::Q2" (aka "const cwg330::Qinner *")
q2 = p; // ok
^

"Test_name.c", line 469: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::R" (aka "const int *const (*)[4]")
r = p;
^

"Test_name.c", line 471: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::S" (aka "const int *const (*)[]")
s = p;
^

"Test_name.c", line 473: error: a value of type "cwg330::P" (aka "int *(*)[3]") cannot be assigned to an entity of type "cwg330::T" (aka "const int *(*)[]")
t = p;
^
Expand Down Expand Up @@ -739,7 +727,7 @@ fe_only -DTEST_NUMBER=5 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
^
detected during instantiation of "void cwg345::f(T) [with T=cwg345::A]" at line 753

"Test_name.c", line 787: warning: return value type does not match the function type
"Test_name.c", line 787: error: return value type does not match the function type
return p;
^
detected during instantiation of "cwg349::A::operator T ***() [with T=const int]" at line 796
Expand Down
Loading
Loading